Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2)  * rk818 battery driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Copyright (C) 2016 Rockchip Electronics Co., Ltd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * chenjh <chenjh@rock-chips.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * This program is free software; you can redistribute it and/or modify it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * under the terms and conditions of the GNU General Public License,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * version 2, as published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * This program is distributed in the hope it will be useful, but WITHOUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  * more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/fb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/iio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/irqdomain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/mfd/rk808.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/of_gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/power_supply.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/power/rk_usbbc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <linux/rk_keys.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <linux/rtc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include <linux/wakelock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include "rk818_battery.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) static int dbg_enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) module_param_named(dbg_level, dbg_enable, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #define DBG(args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 		if (dbg_enable) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 			pr_info(args); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 		} \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #define BAT_INFO(fmt, args...) pr_info("rk818-bat: "fmt, ##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) /* default param */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #define DEFAULT_BAT_RES			135
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define DEFAULT_SLP_ENTER_CUR		300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #define DEFAULT_SLP_EXIT_CUR		300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #define DEFAULT_SLP_FILTER_CUR		100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #define DEFAULT_PWROFF_VOL_THRESD	3400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #define DEFAULT_MONITOR_SEC		5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define DEFAULT_ALGR_VOL_THRESD1	3850
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #define DEFAULT_ALGR_VOL_THRESD2	3950
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #define DEFAULT_MAX_SOC_OFFSET		60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #define DEFAULT_FB_TEMP			TEMP_105C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #define DEFAULT_ZERO_RESERVE_DSOC	10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #define DEFAULT_POFFSET			42
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #define DEFAULT_COFFSET			0x832
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define DEFAULT_SAMPLE_RES		20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #define DEFAULT_ENERGY_MODE		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define INVALID_COFFSET_MIN		0x780
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #define INVALID_COFFSET_MAX		0x980
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #define INVALID_VOL_THRESD		2500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) /* sample resistor and division */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) #define SAMPLE_RES_10MR			10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #define SAMPLE_RES_20MR			20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define SAMPLE_RES_DIV1			1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #define SAMPLE_RES_DIV2			2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) /* virtual params */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #define VIRTUAL_CURRENT			1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define VIRTUAL_VOLTAGE			3888
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) #define VIRTUAL_SOC			66
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) #define VIRTUAL_PRESET			1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) #define VIRTUAL_TEMPERATURE		188
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) #define VIRTUAL_STATUS			POWER_SUPPLY_STATUS_CHARGING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) /* charge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) #define FINISH_CHRG_CUR1			1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) #define FINISH_CHRG_CUR2		1500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) #define FINISH_MAX_SOC_DELAY		20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) #define TERM_CHRG_DSOC			88
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) #define TERM_CHRG_CURR			600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) #define TERM_CHRG_K			650
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) #define SIMULATE_CHRG_INTV		8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) #define SIMULATE_CHRG_CURR		400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) #define SIMULATE_CHRG_K			1500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) #define FULL_CHRG_K			400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) /* zero algorithm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) #define PWROFF_THRESD			3400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) #define MIN_ZERO_DSOC_ACCURACY		10	/*0.01%*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) #define MIN_ZERO_OVERCNT		100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) #define MIN_ACCURACY			1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) #define DEF_PWRPATH_RES			50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) #define	WAIT_DSOC_DROP_SEC		15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) #define	WAIT_SHTD_DROP_SEC		30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) #define ZERO_GAP_XSOC1			10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) #define ZERO_GAP_XSOC2			5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) #define ZERO_GAP_XSOC3			3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) #define ZERO_LOAD_LVL1			1400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) #define ZERO_LOAD_LVL2			600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) #define ZERO_GAP_CALIB			5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) #define ADC_CALIB_THRESHOLD		4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) #define ADC_CALIB_LMT_MIN		3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) #define ADC_CALIB_CNT			5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) #define NTC_CALC_FACTOR			7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) /* time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) #define	POWER_ON_SEC_BASE		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) #define MINUTE(x)			((x) * 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) /* sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) #define SLP_CURR_MAX			40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) #define SLP_CURR_MIN			6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) #define DISCHRG_TIME_STEP1		MINUTE(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) #define DISCHRG_TIME_STEP2		MINUTE(60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) #define SLP_DSOC_VOL_THRESD		3600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) #define REBOOT_PERIOD_SEC		180
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) #define REBOOT_MAX_CNT			80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) /* fcc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) #define MIN_FCC				500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) /* TS detect battery temperature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) #define ADC_CUR_MSK			0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) #define ADC_CUR_20UA			0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) #define ADC_CUR_40UA			0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) #define ADC_CUR_60UA			0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) #define ADC_CUR_80UA			0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) #define NTC_CALC_FACTOR_80UA		7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) #define NTC_CALC_FACTOR_60UA		9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) #define NTC_CALC_FACTOR_40UA		13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) #define NTC_CALC_FACTOR_20UA		27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) #define NTC_80UA_MAX_MEASURE		27500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) #define NTC_60UA_MAX_MEASURE		36666
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) #define NTC_40UA_MAX_MEASURE		55000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) #define NTC_20UA_MAX_MEASURE		110000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) #define INPUT_CUR80MA			(0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) static const char *bat_status[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	"charge off", "dead charge", "trickle charge", "cc cv",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	"finish", "usb over vol", "bat temp error", "timer error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) struct rk818_battery {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	struct platform_device		*pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	struct rk808			*rk818;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	struct regmap			*regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	struct device			*dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	struct power_supply		*bat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	struct power_supply		*usb_psy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	struct power_supply		*ac_psy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	struct battery_platform_data	*pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	struct workqueue_struct		*bat_monitor_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	struct delayed_work		bat_delay_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	struct delayed_work		calib_delay_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	struct wake_lock		wake_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	struct notifier_block           fb_nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	struct timer_list		caltimer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	time64_t			rtc_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	int				bat_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	int				chrg_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	bool				is_initialized;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	bool				is_first_power_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	u8				res_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	int				current_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	int				voltage_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	int				current_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	int				voltage_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	int				voltage_ocv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	int				voltage_relax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	int				voltage_k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	int				voltage_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	int				remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	int				design_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	int				nac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	int				fcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	int				qmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	int				dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	int				rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	int				poffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	int				age_ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	bool				age_allow_update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	int				age_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	int				age_ocv_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	int				age_voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	int				age_adjust_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	unsigned long			age_keep_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	int				zero_timeout_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	int				zero_remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	int				zero_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	int				zero_linek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	u64				zero_drop_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	u64				shtd_drop_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	int				sm_remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	int				sm_linek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	int				sm_chrg_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	int				sm_dischrg_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	int				algo_rest_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	int				algo_rest_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	int				sleep_sum_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	int				sleep_remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	unsigned long			sleep_dischrg_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	unsigned long			sleep_sum_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	bool				sleep_chrg_online;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	u8				sleep_chrg_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	bool				adc_allow_update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	int                             fb_blank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	bool				s2r; /*suspend to resume*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	u32				work_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	int				temperature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	u32				monitor_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	u32				pwroff_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	u32				adc_calib_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	unsigned long			finish_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	unsigned long			boot_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	unsigned long			flat_match_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	unsigned long			plug_in_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	unsigned long			plug_out_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	u8				halt_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	bool				is_halt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	bool				is_max_soc_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	bool				is_sw_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	bool				is_ocv_calib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	bool				is_first_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	bool				is_force_calib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	int				last_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	int				ocv_pre_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	int				ocv_new_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	int				max_pre_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	int				max_new_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	int				force_pre_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	int				force_new_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	int				dbg_cap_low0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	int				dbg_pwr_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	int				dbg_pwr_rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	int				dbg_pwr_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	int				dbg_chrg_min[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	int				dbg_meet_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	int				dbg_calc_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	int				dbg_calc_rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	u8				ac_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	u8				usb_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	int				is_charging;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	unsigned long			charge_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) #define DIV(x)	((x) ? (x) : 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) static u64 get_boot_sec(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	struct timespec64 ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	ktime_get_boottime_ts64(&ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	return ts.tv_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) static unsigned long base2sec(unsigned long x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	if (x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		return (get_boot_sec() > x) ? (get_boot_sec() - x) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) static unsigned long base2min(unsigned long x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	return base2sec(x) / 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) static u32 interpolate(int value, u32 *table, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	u16 d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	for (i = 0; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 		if (value < table[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	if ((i > 0) && (i < size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 		d = (value - table[i - 1]) * (MAX_INTERPOLATE / (size - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		d /= table[i] - table[i - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 		d = d + (i - 1) * (MAX_INTERPOLATE / (size - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 		d = i * ((MAX_INTERPOLATE + size / 2) / size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	if (d > 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 		d = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	return d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) /* (a*b)/c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) static int32_t ab_div_c(u32 a, u32 b, u32 c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	bool sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	u32 ans = MAX_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	sign = ((((a ^ b) ^ c) & 0x80000000) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	if (c != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		if (sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 			c = -c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		tmp = (a * b + (c >> 1)) / c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		if (tmp < MAX_INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 			ans = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	if (sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 		ans = -ans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	return ans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) static int rk818_bat_read(struct rk818_battery *di, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	int ret, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	ret = regmap_read(di->regmap, reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		dev_err(di->dev, "read reg:0x%x failed\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) static int rk818_bat_write(struct rk818_battery *di, u8 reg, u8 buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	ret = regmap_write(di->regmap, reg, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 		dev_err(di->dev, "i2c write reg: 0x%2x error\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) static int rk818_bat_set_bits(struct rk818_battery *di, u8 reg, u8 mask, u8 buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	ret = regmap_update_bits(di->regmap, reg, mask, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		dev_err(di->dev, "write reg:0x%x failed\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) static int rk818_bat_clear_bits(struct rk818_battery *di, u8 reg, u8 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	ret = regmap_update_bits(di->regmap, reg, mask, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		dev_err(di->dev, "clr reg:0x%02x failed\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) static void rk818_bat_dump_regs(struct rk818_battery *di, u8 start, u8 end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	if (!dbg_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	DBG("dump regs from: 0x%x-->0x%x\n", start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	for (i = start; i < end; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 		DBG("0x%x: 0x%0x\n", i, rk818_bat_read(di, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) static bool rk818_bat_chrg_online(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	buf = rk818_bat_read(di, RK818_VB_MON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	return (buf & PLUG_IN_STS) ? true : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) static int rk818_bat_get_coulomb_cap(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	val |= rk818_bat_read(di, RK818_GASCNT3_REG) << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	val |= rk818_bat_read(di, RK818_GASCNT2_REG) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	val |= rk818_bat_read(di, RK818_GASCNT1_REG) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	val |= rk818_bat_read(di, RK818_GASCNT0_REG) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	return (val / 2390) * di->res_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) static int rk818_bat_get_rsoc(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	int remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	remain_cap = rk818_bat_get_coulomb_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	return (remain_cap + di->fcc / 200) * 100 / DIV(di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) static ssize_t bat_info_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 			      const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	char cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	struct rk818_battery *di = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	sscanf(buf, "%c", &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	if (cmd == 'n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		rk818_bat_set_bits(di, RK818_MISC_MARK_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 				   FG_RESET_NOW, FG_RESET_NOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	else if (cmd == 'm')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 		rk818_bat_set_bits(di, RK818_MISC_MARK_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 				   FG_RESET_LATE, FG_RESET_LATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	else if (cmd == 'c')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 		rk818_bat_clear_bits(di, RK818_MISC_MARK_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 				     FG_RESET_LATE | FG_RESET_NOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	else if (cmd == 'r')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 		BAT_INFO("0x%2x\n", rk818_bat_read(di, RK818_MISC_MARK_REG));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		BAT_INFO("command error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) static struct device_attribute rk818_bat_attr[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	__ATTR(bat, 0664, NULL, bat_info_store),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) static void rk818_bat_enable_gauge(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	buf = rk818_bat_read(di, RK818_TS_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	buf |= GG_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	rk818_bat_write(di, RK818_TS_CTRL_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) static void rk818_bat_save_age_level(struct rk818_battery *di, u8 level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	rk818_bat_write(di, RK818_UPDAT_LEVE_REG, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) static u8 rk818_bat_get_age_level(struct  rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	return rk818_bat_read(di, RK818_UPDAT_LEVE_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) static int rk818_bat_get_vcalib0(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	val |= rk818_bat_read(di, RK818_VCALIB0_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	val |= rk818_bat_read(di, RK818_VCALIB0_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	DBG("<%s>. voffset0: 0x%x\n", __func__, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) static int rk818_bat_get_vcalib1(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	val |= rk818_bat_read(di, RK818_VCALIB1_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	val |= rk818_bat_read(di, RK818_VCALIB1_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	DBG("<%s>. voffset1: 0x%x\n", __func__, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) static int rk818_bat_get_ioffset(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	val |= rk818_bat_read(di, RK818_IOFFSET_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	val |= rk818_bat_read(di, RK818_IOFFSET_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	DBG("<%s>. ioffset: 0x%x\n", __func__, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) static int rk818_bat_get_coffset(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	val |= rk818_bat_read(di, RK818_CAL_OFFSET_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	val |= rk818_bat_read(di, RK818_CAL_OFFSET_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	DBG("<%s>. coffset: 0x%x\n", __func__, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) static void rk818_bat_set_coffset(struct rk818_battery *di, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	if ((val < INVALID_COFFSET_MIN) || (val > INVALID_COFFSET_MAX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		BAT_INFO("set invalid coffset=0x%x\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	buf = (val >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	rk818_bat_write(di, RK818_CAL_OFFSET_REGH, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	buf = (val >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	rk818_bat_write(di, RK818_CAL_OFFSET_REGL, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	DBG("<%s>. coffset: 0x%x\n", __func__, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) static void rk818_bat_init_voltage_kb(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	int vcalib0, vcalib1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	vcalib0 = rk818_bat_get_vcalib0(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	vcalib1 = rk818_bat_get_vcalib1(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	di->voltage_k = (4200 - 3000) * 1000 / DIV(vcalib1 - vcalib0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	di->voltage_b = 4200 - (di->voltage_k * vcalib1) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	DBG("voltage_k=%d(*1000),voltage_b=%d\n", di->voltage_k, di->voltage_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) static int rk818_bat_get_ocv_voltage(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	int vol, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	val |= rk818_bat_read(di, RK818_BAT_OCV_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	val |= rk818_bat_read(di, RK818_BAT_OCV_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	vol = di->voltage_k * val / 1000 + di->voltage_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	return vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) static int rk818_bat_get_avg_voltage(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	int vol, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	val |= rk818_bat_read(di, RK818_BAT_VOL_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	val |= rk818_bat_read(di, RK818_BAT_VOL_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	vol = di->voltage_k * val / 1000 + di->voltage_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	return vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) static bool is_rk818_bat_relax_mode(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	status = rk818_bat_read(di, RK818_GGSTS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	if (!(status & RELAX_VOL1_UPD) || !(status & RELAX_VOL2_UPD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) static u16 rk818_bat_get_relax_vol1(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	u16 vol, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	val |= rk818_bat_read(di, RK818_RELAX_VOL1_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	val |= rk818_bat_read(di, RK818_RELAX_VOL1_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	vol = di->voltage_k * val / 1000 + di->voltage_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	return vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) static u16 rk818_bat_get_relax_vol2(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	u16 vol, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	val |= rk818_bat_read(di, RK818_RELAX_VOL2_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	val |= rk818_bat_read(di, RK818_RELAX_VOL2_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	vol = di->voltage_k * val / 1000 + di->voltage_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	return vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) static u16 rk818_bat_get_relax_voltage(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	u16 relax_vol1, relax_vol2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	if (!is_rk818_bat_relax_mode(di))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	relax_vol1 = rk818_bat_get_relax_vol1(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	relax_vol2 = rk818_bat_get_relax_vol2(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	return relax_vol1 > relax_vol2 ? relax_vol1 : relax_vol2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) static int rk818_bat_get_avg_current(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	int cur, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	val |= rk818_bat_read(di, RK818_BAT_CUR_AVG_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	val |= rk818_bat_read(di, RK818_BAT_CUR_AVG_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	if (val & 0x800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		val -= 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	cur = val * di->res_div * 1506 / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	return cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) static int rk818_bat_vol_to_ocvsoc(struct rk818_battery *di, int voltage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	u32 *ocv_table, temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	int ocv_size, ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	ocv_table = di->pdata->ocv_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	ocv_size = di->pdata->ocv_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	temp = interpolate(voltage, ocv_table, ocv_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	ocv_soc = ab_div_c(temp, MAX_PERCENTAGE, MAX_INTERPOLATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	return ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) static int rk818_bat_vol_to_ocvcap(struct rk818_battery *di, int voltage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	u32 *ocv_table, temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	int ocv_size, cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	ocv_table = di->pdata->ocv_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	ocv_size = di->pdata->ocv_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	temp = interpolate(voltage, ocv_table, ocv_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	cap = ab_div_c(temp, di->fcc, MAX_INTERPOLATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	return cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) static int rk818_bat_vol_to_zerosoc(struct rk818_battery *di, int voltage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	u32 *ocv_table, temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	int ocv_size, ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	ocv_table = di->pdata->zero_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	ocv_size = di->pdata->ocv_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	temp = interpolate(voltage, ocv_table, ocv_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	ocv_soc = ab_div_c(temp, MAX_PERCENTAGE, MAX_INTERPOLATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	return ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) static int rk818_bat_vol_to_zerocap(struct rk818_battery *di, int voltage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	u32 *ocv_table, temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	int ocv_size, cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	ocv_table = di->pdata->zero_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	ocv_size = di->pdata->ocv_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	temp = interpolate(voltage, ocv_table, ocv_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	cap = ab_div_c(temp, di->fcc, MAX_INTERPOLATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	return cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) static int rk818_bat_get_iadc(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	val |= rk818_bat_read(di, RK818_BAT_CUR_AVG_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	val |= rk818_bat_read(di, RK818_BAT_CUR_AVG_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	if (val > 2047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		val -= 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) static bool rk818_bat_adc_calib(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	int i, ioffset, coffset, adc, save_coffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	if ((di->chrg_status != CHARGE_FINISH) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	    (di->adc_calib_cnt > ADC_CALIB_CNT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	    (base2min(di->boot_base) < ADC_CALIB_LMT_MIN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	    (abs(di->current_avg) < ADC_CALIB_THRESHOLD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	di->adc_calib_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	save_coffset = rk818_bat_get_coffset(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	for (i = 0; i < 5; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		adc = rk818_bat_get_iadc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		if (!rk818_bat_chrg_online(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 			rk818_bat_set_coffset(di, save_coffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 			BAT_INFO("quit, charger plugout when calib adc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		coffset = rk818_bat_get_coffset(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		rk818_bat_set_coffset(di, coffset + adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		msleep(2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		adc = rk818_bat_get_iadc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 		if (abs(adc) < ADC_CALIB_THRESHOLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 			coffset = rk818_bat_get_coffset(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 			ioffset = rk818_bat_get_ioffset(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 			di->poffset = coffset - ioffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 			rk818_bat_write(di, RK818_POFFSET_REG, di->poffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 			BAT_INFO("new offset:c=0x%x, i=0x%x, p=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 				 coffset, ioffset, di->poffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 			BAT_INFO("coffset calib again %d.., max_cnt=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 				 i, di->adc_calib_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 			rk818_bat_set_coffset(di, coffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 			msleep(2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	rk818_bat_set_coffset(di, save_coffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) static void rk818_bat_set_ioffset_sample(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	u8 ggcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	ggcon = rk818_bat_read(di, RK818_GGCON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	ggcon &= ~ADC_CAL_MIN_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	ggcon |= ADC_CAL_8MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	rk818_bat_write(di, RK818_GGCON_REG, ggcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) static void rk818_bat_set_ocv_sample(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	u8 ggcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	ggcon = rk818_bat_read(di, RK818_GGCON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	ggcon &= ~OCV_SAMP_MIN_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	ggcon |= OCV_SAMP_8MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	rk818_bat_write(di, RK818_GGCON_REG, ggcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) static void rk818_bat_restart_relax(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	u8 ggsts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	ggsts = rk818_bat_read(di, RK818_GGSTS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	ggsts &= ~RELAX_VOL12_UPD_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	rk818_bat_write(di, RK818_GGSTS_REG, ggsts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) static void rk818_bat_set_relax_sample(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	int enter_thres, exit_thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	struct battery_platform_data *pdata = di->pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	enter_thres = pdata->sleep_enter_current * 1000 / 1506 / DIV(di->res_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	exit_thres = pdata->sleep_exit_current * 1000 / 1506 / DIV(di->res_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	/* set relax enter and exit threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	buf = enter_thres & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	rk818_bat_write(di, RK818_RELAX_ENTRY_THRES_REGL, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	buf = (enter_thres >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	rk818_bat_write(di, RK818_RELAX_ENTRY_THRES_REGH, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	buf = exit_thres & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	rk818_bat_write(di, RK818_RELAX_EXIT_THRES_REGL, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	buf = (exit_thres >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	rk818_bat_write(di, RK818_RELAX_EXIT_THRES_REGH, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	/* reset relax update state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	rk818_bat_restart_relax(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	DBG("<%s>. sleep_enter_current = %d, sleep_exit_current = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	    __func__, pdata->sleep_enter_current, pdata->sleep_exit_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) static bool is_rk818_bat_exist(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	return (rk818_bat_read(di, RK818_SUP_STS_REG) & BAT_EXS) ? true : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) static bool is_rk818_bat_first_pwron(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	buf = rk818_bat_read(di, RK818_GGSTS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	if (buf & BAT_CON) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		buf &= ~BAT_CON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 		rk818_bat_write(di, RK818_GGSTS_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) static u8 rk818_bat_get_pwroff_min(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	u8 cur, last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	cur = rk818_bat_read(di, RK818_NON_ACT_TIMER_CNT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	last = rk818_bat_read(di, RK818_NON_ACT_TIMER_CNT_SAVE_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	rk818_bat_write(di, RK818_NON_ACT_TIMER_CNT_SAVE_REG, cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	return (cur != last) ? cur : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) static u8 is_rk818_bat_initialized(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	u8 val = rk818_bat_read(di, RK818_MISC_MARK_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	if (val & FG_INIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		val &= ~FG_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		rk818_bat_write(di, RK818_MISC_MARK_REG, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) static bool is_rk818_bat_ocv_valid(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	return (!di->is_initialized && di->pwroff_min >= 30) ? true : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) static void rk818_bat_init_age_algorithm(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	int age_level, ocv_soc, ocv_cap, ocv_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	if (di->is_first_power_on || is_rk818_bat_ocv_valid(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		DBG("<%s> enter.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 		ocv_vol = rk818_bat_get_ocv_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		ocv_soc = rk818_bat_vol_to_ocvsoc(di, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		ocv_cap = rk818_bat_vol_to_ocvcap(di, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		if (ocv_soc < 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 			di->age_voltage = ocv_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 			di->age_ocv_cap = ocv_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 			di->age_ocv_soc = ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 			di->age_adjust_cap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 			if (ocv_soc <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 				di->age_level = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 			else if (ocv_soc < 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 				di->age_level = 95;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 			else if (ocv_soc < 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 				di->age_level = 90;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 				di->age_level = 80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 			age_level = rk818_bat_get_age_level(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 			if (age_level > di->age_level) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 				di->age_allow_update = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 				age_level -= 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 				if (age_level <= 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 					age_level = 80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 				rk818_bat_save_age_level(di, age_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 				di->age_allow_update = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 				di->age_keep_sec = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 			BAT_INFO("init_age_algorithm: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 				 "age_vol:%d, age_ocv_cap:%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 				 "age_ocv_soc:%d, old_age_level:%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 				 "age_allow_update:%d, new_age_level:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 				 di->age_voltage, di->age_ocv_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 				 ocv_soc, age_level, di->age_allow_update,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 				 di->age_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) static enum power_supply_property rk818_bat_props[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	POWER_SUPPLY_PROP_CURRENT_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	POWER_SUPPLY_PROP_PRESENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	POWER_SUPPLY_PROP_HEALTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	POWER_SUPPLY_PROP_CAPACITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	POWER_SUPPLY_PROP_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	POWER_SUPPLY_PROP_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	POWER_SUPPLY_PROP_CHARGE_COUNTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	POWER_SUPPLY_PROP_CHARGE_FULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	POWER_SUPPLY_PROP_VOLTAGE_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	POWER_SUPPLY_PROP_CURRENT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) static int rk818_bat_get_usb_psy(struct device *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	struct rk818_battery *di = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	struct power_supply *psy = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	if (psy->desc->type == POWER_SUPPLY_TYPE_USB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 		di->usb_psy = psy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) static int rk818_bat_get_ac_psy(struct device *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	struct rk818_battery *di = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	struct power_supply *psy = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	if (psy->desc->type == POWER_SUPPLY_TYPE_MAINS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		di->ac_psy = psy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) static void rk818_bat_get_chrg_psy(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	if (!di->usb_psy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		class_for_each_device(power_supply_class, NULL, (void *)di,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 				      rk818_bat_get_usb_psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	if (!di->ac_psy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		class_for_each_device(power_supply_class, NULL, (void *)di,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 				      rk818_bat_get_ac_psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) static int rk818_bat_get_charge_state(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	union power_supply_propval val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	if (!di->usb_psy || !di->ac_psy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 		rk818_bat_get_chrg_psy(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	if (di->usb_psy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		ret = di->usb_psy->desc->get_property(di->usb_psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 						      POWER_SUPPLY_PROP_ONLINE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 						      &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 			di->usb_in = val.intval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	if (di->ac_psy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		ret = di->ac_psy->desc->get_property(di->ac_psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 						     POWER_SUPPLY_PROP_ONLINE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 						     &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 			di->ac_in = val.intval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	DBG("%s: ac_online=%d, usb_online=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	    __func__, di->ac_in, di->usb_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	return (di->usb_in || di->ac_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) static int rk818_get_capacity_leve(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	if (di->pdata->bat_mode == MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		return POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	if (di->dsoc < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		return POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	else if (di->dsoc <= 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 		return POWER_SUPPLY_CAPACITY_LEVEL_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	else if (di->dsoc <= 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		return POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	else if (di->dsoc <= 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		return POWER_SUPPLY_CAPACITY_LEVEL_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		return POWER_SUPPLY_CAPACITY_LEVEL_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) static int rk818_battery_time_to_full(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	int time_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	int cap_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	if (di->pdata->bat_mode == MODE_VIRTUAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		time_sec = 3600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	} else if (di->voltage_avg > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		cap_temp = di->pdata->design_capacity - di->remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		if (cap_temp < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 			cap_temp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		time_sec = (3600 * cap_temp) / di->voltage_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		time_sec = 3600 * 24; /* One day */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	return time_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) static int rk818_battery_get_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 				      enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 				      union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	struct rk818_battery *di = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	case POWER_SUPPLY_PROP_CURRENT_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		val->intval = di->current_avg * 1000;/*uA*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		if (di->pdata->bat_mode == MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 			val->intval = VIRTUAL_CURRENT * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		val->intval = di->voltage_avg * 1000;/*uV*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 		if (di->pdata->bat_mode == MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 			val->intval = VIRTUAL_VOLTAGE * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	case POWER_SUPPLY_PROP_PRESENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		val->intval = is_rk818_bat_exist(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		if (di->pdata->bat_mode == MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 			val->intval = VIRTUAL_PRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	case POWER_SUPPLY_PROP_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		val->intval = di->dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		if (di->pdata->bat_mode == MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 			val->intval = VIRTUAL_SOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		DBG("<%s>. report dsoc: %d\n", __func__, val->intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 		val->intval = rk818_get_capacity_leve(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	case POWER_SUPPLY_PROP_HEALTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		val->intval = POWER_SUPPLY_HEALTH_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	case POWER_SUPPLY_PROP_TEMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		val->intval = di->temperature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		if (di->pdata->bat_mode == MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 			val->intval = VIRTUAL_TEMPERATURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	case POWER_SUPPLY_PROP_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 		if (di->pdata->bat_mode == MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 			val->intval = VIRTUAL_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		else if (di->dsoc == 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 			val->intval = POWER_SUPPLY_STATUS_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		else if (rk818_bat_get_charge_state(di))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	case POWER_SUPPLY_PROP_CHARGE_COUNTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		val->intval = di->charge_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	case POWER_SUPPLY_PROP_CHARGE_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		val->intval = di->pdata->design_capacity * 1000;/* uAh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		val->intval = rk818_battery_time_to_full(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		val->intval = di->voltage_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	case POWER_SUPPLY_PROP_CURRENT_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		val->intval = di->current_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) static const struct power_supply_desc rk818_bat_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	.name		= "battery",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	.type		= POWER_SUPPLY_TYPE_BATTERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	.properties	= rk818_bat_props,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	.num_properties	= ARRAY_SIZE(rk818_bat_props),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	.get_property	= rk818_battery_get_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) static int rk818_bat_init_power_supply(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	struct power_supply_config psy_cfg = { .drv_data = di, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	di->bat = devm_power_supply_register(di->dev, &rk818_bat_desc, &psy_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	if (IS_ERR(di->bat)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 		dev_err(di->dev, "register bat power supply fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		return PTR_ERR(di->bat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) static void rk818_bat_save_cap(struct rk818_battery *di, int cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	static u32 old_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	if (cap >= di->qmax)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 		cap = di->qmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	if (cap <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		cap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	if (old_cap == cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	old_cap = cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	buf = (cap >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	rk818_bat_write(di, RK818_REMAIN_CAP_REG3, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	buf = (cap >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	rk818_bat_write(di, RK818_REMAIN_CAP_REG2, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	buf = (cap >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	rk818_bat_write(di, RK818_REMAIN_CAP_REG1, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	buf = (cap >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	rk818_bat_write(di, RK818_REMAIN_CAP_REG0, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) static int rk818_bat_get_prev_cap(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	val |= rk818_bat_read(di, RK818_REMAIN_CAP_REG3) << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	val |= rk818_bat_read(di, RK818_REMAIN_CAP_REG2) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	val |= rk818_bat_read(di, RK818_REMAIN_CAP_REG1) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	val |= rk818_bat_read(di, RK818_REMAIN_CAP_REG0) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) static void rk818_bat_save_fcc(struct rk818_battery *di, u32 fcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	buf = (fcc >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	rk818_bat_write(di, RK818_NEW_FCC_REG3, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	buf = (fcc >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	rk818_bat_write(di, RK818_NEW_FCC_REG2, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	buf = (fcc >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	rk818_bat_write(di, RK818_NEW_FCC_REG1, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	buf = (fcc >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	rk818_bat_write(di, RK818_NEW_FCC_REG0, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	BAT_INFO("save fcc: %d\n", fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) static int rk818_bat_get_fcc(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	u32 fcc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	fcc |= rk818_bat_read(di, RK818_NEW_FCC_REG3) << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	fcc |= rk818_bat_read(di, RK818_NEW_FCC_REG2) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	fcc |= rk818_bat_read(di, RK818_NEW_FCC_REG1) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	fcc |= rk818_bat_read(di, RK818_NEW_FCC_REG0) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	if (fcc < MIN_FCC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 		BAT_INFO("invalid fcc(%d), use design cap", fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 		fcc = di->pdata->design_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 		rk818_bat_save_fcc(di, fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	} else if (fcc > di->pdata->design_qmax) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 		BAT_INFO("invalid fcc(%d), use qmax", fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 		fcc = di->pdata->design_qmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 		rk818_bat_save_fcc(di, fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	return fcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) static void rk818_bat_init_coulomb_cap(struct rk818_battery *di, u32 capacity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	u32 cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	cap = capacity * 2390 / DIV(di->res_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	buf = (cap >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	rk818_bat_write(di, RK818_GASCNT_CAL_REG3, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	buf = (cap >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	rk818_bat_write(di, RK818_GASCNT_CAL_REG2, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	buf = (cap >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	rk818_bat_write(di, RK818_GASCNT_CAL_REG1, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	buf = ((cap >> 0) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	rk818_bat_write(di, RK818_GASCNT_CAL_REG0, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	DBG("<%s>. new coulomb cap = %d\n", __func__, capacity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	di->remain_cap = capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	di->rsoc = rk818_bat_get_rsoc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) static void rk818_bat_save_dsoc(struct rk818_battery *di, u8 save_soc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	static int last_soc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	if (last_soc != save_soc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 		rk818_bat_write(di, RK818_SOC_REG, save_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 		last_soc = save_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) static int rk818_bat_get_prev_dsoc(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	return rk818_bat_read(di, RK818_SOC_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) static void rk818_bat_save_reboot_cnt(struct rk818_battery *di, u8 save_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	rk818_bat_write(di, RK818_REBOOT_CNT_REG, save_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) static int rk818_bat_fb_notifier(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 				 unsigned long event, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	struct rk818_battery *di;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	struct fb_event *evdata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	if (event != FB_EVENT_BLANK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 		return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	di = container_of(nb, struct rk818_battery, fb_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	di->fb_blank = *(int *)evdata->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) static int rk818_bat_register_fb_notify(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	memset(&di->fb_nb, 0, sizeof(di->fb_nb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	di->fb_nb.notifier_call = rk818_bat_fb_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	return fb_register_client(&di->fb_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) static int rk818_bat_unregister_fb_notify(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	return fb_unregister_client(&di->fb_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) static u8 rk818_bat_get_halt_cnt(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	return rk818_bat_read(di, RK818_HALT_CNT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) static void rk818_bat_inc_halt_cnt(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	u8 cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	cnt = rk818_bat_read(di, RK818_HALT_CNT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	rk818_bat_write(di, RK818_HALT_CNT_REG, ++cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) static bool is_rk818_bat_last_halt(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	int pre_cap = rk818_bat_get_prev_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	int now_cap = rk818_bat_get_coulomb_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	/* over 10%: system halt last time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	if (abs(now_cap - pre_cap) > (di->fcc / 10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 		rk818_bat_inc_halt_cnt(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) static void rk818_bat_first_pwron(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	int ocv_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	rk818_bat_save_fcc(di, di->design_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	ocv_vol = rk818_bat_get_ocv_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 	di->fcc = rk818_bat_get_fcc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	di->nac = rk818_bat_vol_to_ocvcap(di, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	di->rsoc = rk818_bat_vol_to_ocvsoc(di, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	di->dsoc = di->rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	di->is_first_on = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	BAT_INFO("first on: dsoc=%d, rsoc=%d cap=%d, fcc=%d, ov=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 		 di->dsoc, di->rsoc, di->nac, di->fcc, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) static void rk818_bat_not_first_pwron(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	int now_cap, pre_soc, pre_cap, ocv_cap, ocv_soc, ocv_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	di->fcc = rk818_bat_get_fcc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	pre_soc = rk818_bat_get_prev_dsoc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	pre_cap = rk818_bat_get_prev_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	now_cap = rk818_bat_get_coulomb_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	di->is_halt = is_rk818_bat_last_halt(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	di->halt_cnt = rk818_bat_get_halt_cnt(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	di->is_initialized = is_rk818_bat_initialized(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	di->is_ocv_calib = is_rk818_bat_ocv_valid(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	if (di->is_initialized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 		BAT_INFO("initialized yet..\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 		goto finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	} else if (di->is_halt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 		BAT_INFO("system halt last time... cap: pre=%d, now=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 			 pre_cap, now_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 		if (now_cap < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 			now_cap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 		rk818_bat_init_coulomb_cap(di, now_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 		pre_cap = now_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 		pre_soc = di->rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 		goto finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	} else if (di->is_ocv_calib) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 		ocv_vol = rk818_bat_get_ocv_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 		ocv_soc = rk818_bat_vol_to_ocvsoc(di, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 		ocv_cap = rk818_bat_vol_to_ocvcap(di, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 		pre_cap = ocv_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 		di->ocv_pre_dsoc = pre_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 		di->ocv_new_dsoc = ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 		if (abs(ocv_soc - pre_soc) >= di->pdata->max_soc_offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 			di->ocv_pre_dsoc = pre_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 			di->ocv_new_dsoc = ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 			di->is_max_soc_offset = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 			BAT_INFO("trigger max soc offset, dsoc: %d -> %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 				 pre_soc, ocv_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 			pre_soc = ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 		BAT_INFO("OCV calib: cap=%d, rsoc=%d\n", ocv_cap, ocv_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	} else if (di->pwroff_min > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 		ocv_vol = rk818_bat_get_ocv_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 		ocv_soc = rk818_bat_vol_to_ocvsoc(di, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 		ocv_cap = rk818_bat_vol_to_ocvcap(di, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 		di->force_pre_dsoc = pre_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 		di->force_new_dsoc = ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 		if (abs(ocv_soc - pre_soc) >= 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 			di->is_force_calib = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 			BAT_INFO("dsoc force calib: %d -> %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 				 pre_soc, ocv_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 			pre_soc = ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 			pre_cap = ocv_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	di->dsoc = pre_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	di->nac = pre_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	if (di->nac < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 		di->nac = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	BAT_INFO("dsoc=%d cap=%d v=%d ov=%d rv=%d min=%d psoc=%d pcap=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 		 di->dsoc, di->nac, rk818_bat_get_avg_voltage(di),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 		 rk818_bat_get_ocv_voltage(di), rk818_bat_get_relax_voltage(di),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 		 di->pwroff_min, rk818_bat_get_prev_dsoc(di),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 		 rk818_bat_get_prev_cap(di));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) static bool rk818_bat_ocv_sw_reset(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	buf = rk818_bat_read(di, RK818_MISC_MARK_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	if (((buf & FG_RESET_LATE) && di->pwroff_min >= 30) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	    (buf & FG_RESET_NOW)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 		buf &= ~FG_RESET_LATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 		buf &= ~FG_RESET_NOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 		rk818_bat_write(di, RK818_MISC_MARK_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 		BAT_INFO("manual reset fuel gauge\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) static void rk818_bat_init_rsoc(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	di->is_first_power_on = is_rk818_bat_first_pwron(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	di->is_sw_reset = rk818_bat_ocv_sw_reset(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	di->pwroff_min = rk818_bat_get_pwroff_min(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	if (di->is_first_power_on || di->is_sw_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 		rk818_bat_first_pwron(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		rk818_bat_not_first_pwron(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) static u8 rk818_bat_get_chrg_status(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	status = rk818_bat_read(di, RK818_SUP_STS_REG) & CHRG_STATUS_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	case CHARGE_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 		DBG("CHARGE-OFF ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	case DEAD_CHARGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 		BAT_INFO("DEAD CHARGE...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	case TRICKLE_CHARGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 		BAT_INFO("TRICKLE CHARGE...\n ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 	case CC_OR_CV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 		DBG("CC or CV...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	case CHARGE_FINISH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 		DBG("CHARGE FINISH...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	case USB_OVER_VOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 		BAT_INFO("USB OVER VOL...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	case BAT_TMP_ERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 		BAT_INFO("BAT TMP ERROR...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	case TIMER_ERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 		BAT_INFO("TIMER ERROR...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 	case USB_EXIST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 		BAT_INFO("USB EXIST...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	case USB_EFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 		BAT_INFO("USB EFF...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) static u8 rk818_bat_parse_fb_temperature(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	int index, fb_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	reg = DEFAULT_FB_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	fb_temp = di->pdata->fb_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	for (index = 0; index < ARRAY_SIZE(feedback_temp_array); index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 		if (fb_temp < feedback_temp_array[index])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 		reg = (index << FB_TEMP_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) static u8 rk818_bat_parse_finish_ma(struct rk818_battery *di, int fcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	u8 ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 	if (di->pdata->sample_res == SAMPLE_RES_10MR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 		ma = FINISH_100MA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	else if (fcc > 5000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 		ma = FINISH_250MA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	else if (fcc >= 4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 		ma = FINISH_200MA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	else if (fcc >= 3000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 		ma = FINISH_150MA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 		ma = FINISH_100MA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	return ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) static void rk818_bat_init_chrg_config(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	u8 usb_ctrl, chrg_ctrl2, chrg_ctrl3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	u8 thermal, ggcon, finish_ma, fb_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	finish_ma = rk818_bat_parse_finish_ma(di, di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	fb_temp = rk818_bat_parse_fb_temperature(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	ggcon = rk818_bat_read(di, RK818_GGCON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	thermal = rk818_bat_read(di, RK818_THERMAL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	usb_ctrl = rk818_bat_read(di, RK818_USB_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	chrg_ctrl2 = rk818_bat_read(di, RK818_CHRG_CTRL_REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 	chrg_ctrl3 = rk818_bat_read(di, RK818_CHRG_CTRL_REG3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	/* set charge finish current */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	chrg_ctrl3 |= CHRG_TERM_DIG_SIGNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 	chrg_ctrl2 &= ~FINISH_CUR_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	chrg_ctrl2 |= finish_ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	/* disable cccv mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 	chrg_ctrl3 &= ~CHRG_TIMER_CCCV_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 	/* set feed back temperature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 	if (di->pdata->fb_temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 		usb_ctrl |= CHRG_CT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 		usb_ctrl &= ~CHRG_CT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 	thermal &= ~FB_TEMP_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 	thermal |= fb_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 	/* adc current mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	ggcon |= ADC_CUR_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 	rk818_bat_write(di, RK818_GGCON_REG, ggcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 	rk818_bat_write(di, RK818_THERMAL_REG, thermal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 	rk818_bat_write(di, RK818_USB_CTRL_REG, usb_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	rk818_bat_write(di, RK818_CHRG_CTRL_REG2, chrg_ctrl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	rk818_bat_write(di, RK818_CHRG_CTRL_REG3, chrg_ctrl3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) static void rk818_bat_init_coffset(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	int coffset, ioffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 	ioffset = rk818_bat_get_ioffset(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	di->poffset = rk818_bat_read(di, RK818_POFFSET_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	if (!di->poffset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 		di->poffset = DEFAULT_POFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 	coffset = di->poffset + ioffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 	if (coffset < INVALID_COFFSET_MIN || coffset > INVALID_COFFSET_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 		coffset = DEFAULT_COFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 	rk818_bat_set_coffset(di, coffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 	DBG("<%s>. offset: p=0x%x, i=0x%x, c=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 	    __func__, di->poffset, ioffset, rk818_bat_get_coffset(di));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) static void rk818_bat_caltimer_isr(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	struct rk818_battery *di = from_timer(di, t, caltimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 	mod_timer(&di->caltimer, jiffies + MINUTE(8) * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 	queue_delayed_work(di->bat_monitor_wq, &di->calib_delay_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 			   msecs_to_jiffies(10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) static void rk818_bat_internal_calib(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	int ioffset, poffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	struct rk818_battery *di = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 			struct rk818_battery, calib_delay_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	/* calib coffset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	poffset = rk818_bat_read(di, RK818_POFFSET_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 	if (poffset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 		di->poffset = poffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 		di->poffset = DEFAULT_POFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 	ioffset = rk818_bat_get_ioffset(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	rk818_bat_set_coffset(di, ioffset + di->poffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	/* calib voltage kb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	rk818_bat_init_voltage_kb(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	BAT_INFO("caltimer: ioffset=0x%x, coffset=0x%x, poffset=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 		 ioffset, rk818_bat_get_coffset(di), di->poffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) static void rk818_bat_init_caltimer(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	timer_setup(&di->caltimer, rk818_bat_caltimer_isr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	di->caltimer.expires = jiffies + MINUTE(8) * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 	add_timer(&di->caltimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	INIT_DELAYED_WORK(&di->calib_delay_work, rk818_bat_internal_calib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) static void rk818_bat_init_zero_table(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 	int i, diff, min, max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 	size_t ocv_size, length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	ocv_size = di->pdata->ocv_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	length = sizeof(di->pdata->zero_table) * ocv_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	di->pdata->zero_table =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 			devm_kzalloc(di->dev, length, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	if (!di->pdata->zero_table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 		di->pdata->zero_table = di->pdata->ocv_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 		dev_err(di->dev, "malloc zero table fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 	min = di->pdata->pwroff_vol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	max = di->pdata->ocv_table[ocv_size - 4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 	diff = (max - min) / DIV(ocv_size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 	for (i = 0; i < ocv_size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 		di->pdata->zero_table[i] = min + (i * diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	for (i = 0; i < ocv_size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 		DBG("zero[%d] = %d\n", i, di->pdata->zero_table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	for (i = 0; i < ocv_size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 		DBG("ocv[%d] = %d\n", i, di->pdata->ocv_table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) static void rk818_bat_calc_sm_linek(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 	int linek, current_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	u8 diff, delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	delta = abs(di->dsoc - di->rsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	diff = delta * 3;/* speed:3/4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	current_avg = rk818_bat_get_avg_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 	if (current_avg >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 		if (di->dsoc < di->rsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 			linek = 1000 * (delta + diff) / DIV(diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 		else if (di->dsoc > di->rsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 			linek = 1000 * diff / DIV(delta + diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 			linek = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 		di->dbg_meet_soc = (di->dsoc >= di->rsoc) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 				   (di->dsoc + diff) : (di->rsoc + diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 		if (di->dsoc < di->rsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 			linek = -1000 * diff / DIV(delta + diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 		else if (di->dsoc > di->rsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 			linek = -1000 * (delta + diff) / DIV(diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 			linek = -1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 		di->dbg_meet_soc = (di->dsoc >= di->rsoc) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 				   (di->dsoc - diff) : (di->rsoc - diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	di->sm_linek = linek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	di->sm_remain_cap = di->remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 	di->dbg_calc_dsoc = di->dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	di->dbg_calc_rsoc = di->rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	DBG("<%s>.diff=%d, k=%d, cur=%d\n", __func__, diff, linek, current_avg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) static void rk818_bat_calc_zero_linek(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	int dead_voltage, ocv_voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	int voltage_avg, current_avg, vsys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	int ocv_cap, dead_cap, xsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 	int ocv_soc, dead_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	int pwroff_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 	int i, cnt = 0, vol_old, vol_now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 	int org_linek = 0, min_gap_xsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 	if ((abs(di->current_avg) < 500) && (di->dsoc > 10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 		pwroff_vol = di->pdata->pwroff_vol + 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 		pwroff_vol = di->pdata->pwroff_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 		vol_old = rk818_bat_get_avg_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 		msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 		vol_now = rk818_bat_get_avg_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 		cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	} while ((vol_old == vol_now) && (cnt < 11));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	voltage_avg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	for (i = 0; i < 10; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 		voltage_avg += rk818_bat_get_avg_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 		msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	/* calc estimate ocv voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	voltage_avg /= 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 	current_avg = rk818_bat_get_avg_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 	vsys = voltage_avg + (current_avg * DEF_PWRPATH_RES) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	DBG("ZERO0: shtd_vol: org = %d, now = %d, zero_reserve_dsoc = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 	    di->pdata->pwroff_vol, pwroff_vol, di->pdata->zero_reserve_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 	dead_voltage = pwroff_vol - current_avg *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 				(di->bat_res + DEF_PWRPATH_RES) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 	ocv_voltage = voltage_avg - (current_avg * di->bat_res) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 	DBG("ZERO0: dead_voltage(shtd) = %d, ocv_voltage(now) = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	    dead_voltage, ocv_voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	/* calc estimate soc and cap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	dead_soc = rk818_bat_vol_to_zerosoc(di, dead_voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	dead_cap = rk818_bat_vol_to_zerocap(di, dead_voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	DBG("ZERO0: dead_soc = %d, dead_cap = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 	    dead_soc, dead_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 	ocv_soc = rk818_bat_vol_to_zerosoc(di, ocv_voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 	ocv_cap = rk818_bat_vol_to_zerocap(di, ocv_voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 	DBG("ZERO0: ocv_soc = %d, ocv_cap = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	    ocv_soc, ocv_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 	/* xsoc: available rsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 	xsoc = ocv_soc - dead_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	/* min_gap_xsoc: reserve xsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 	if (abs(current_avg) > ZERO_LOAD_LVL1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 		min_gap_xsoc = ZERO_GAP_XSOC3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	else if (abs(current_avg) > ZERO_LOAD_LVL2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 		min_gap_xsoc = ZERO_GAP_XSOC2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 		min_gap_xsoc = ZERO_GAP_XSOC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 	if ((xsoc <= 30) && (di->dsoc >= di->pdata->zero_reserve_dsoc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 		min_gap_xsoc = min_gap_xsoc + ZERO_GAP_CALIB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	di->zero_remain_cap = di->remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 	di->zero_timeout_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	if ((di->dsoc <= 1) && (xsoc > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 		di->zero_linek = 400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 		di->zero_drop_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	} else if (xsoc >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 		di->zero_drop_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 		di->zero_linek = (di->zero_dsoc + xsoc / 2) / DIV(xsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 		org_linek = di->zero_linek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 		/* battery energy mode to use up voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 		if ((di->pdata->energy_mode) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 		    (xsoc - di->dsoc >= ZERO_GAP_XSOC3) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 		    (di->dsoc <= 10) && (di->zero_linek < 300)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 			di->zero_linek = 300;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 			DBG("ZERO-new: zero_linek adjust step0...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 		/* reserve enough power yet, slow down any way */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 		} else if ((xsoc - di->dsoc >= min_gap_xsoc) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 			   ((xsoc - di->dsoc >= ZERO_GAP_XSOC2) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 			    (di->dsoc <= 10) && (xsoc > 15))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 			if (xsoc <= 20 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 			    di->dsoc >= di->pdata->zero_reserve_dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 				di->zero_linek = 1200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 			else if (xsoc - di->dsoc >= 2 * min_gap_xsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 				di->zero_linek = 400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 			else if (xsoc - di->dsoc >= 3 + min_gap_xsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 				di->zero_linek = 600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 				di->zero_linek = 800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 			DBG("ZERO-new: zero_linek adjust step1...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 		/* control zero mode beginning enter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 		} else if ((di->zero_linek > 1800) && (di->dsoc > 70)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 			di->zero_linek = 1800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 			DBG("ZERO-new: zero_linek adjust step2...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 		/* dsoc close to xsoc: it must reserve power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 		} else if ((di->zero_linek > 1000) && (di->zero_linek < 1200)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 			di->zero_linek = 1200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 			DBG("ZERO-new: zero_linek adjust step3...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 		/* dsoc[5~15], dsoc < xsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 		} else if ((di->dsoc <= 15 && di->dsoc > 5) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 			   (di->zero_linek <= 1200)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 			/* slow down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 			if (xsoc - di->dsoc >= min_gap_xsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 				di->zero_linek = 800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 			/* reserve power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 				di->zero_linek = 1200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 			DBG("ZERO-new: zero_linek adjust step4...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 		/* dsoc[5, 100], dsoc < xsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 		} else if ((di->zero_linek < 1000) && (di->dsoc >= 5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 			if ((xsoc - di->dsoc) < min_gap_xsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 				/* reserve power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 				di->zero_linek = 1200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 				if (abs(di->current_avg) > 500)/* heavy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 					di->zero_linek = 900;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 					di->zero_linek = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 			DBG("ZERO-new: zero_linek adjust step5...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 		/* dsoc[0~5], dsoc < xsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 		} else if ((di->zero_linek < 1000) && (di->dsoc <= 5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 			if ((xsoc - di->dsoc) <= 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 				di->zero_linek = 1200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 				di->zero_linek = 800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 				DBG("ZERO-new: zero_linek adjust step6...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		/* xsoc < 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 		di->zero_linek = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 		if (!di->zero_drop_sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 			di->zero_drop_sec = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 		if (base2sec(di->zero_drop_sec) >= WAIT_DSOC_DROP_SEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 			DBG("ZERO0: t=%lu\n", base2sec(di->zero_drop_sec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 			di->zero_drop_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 			di->dsoc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 			di->zero_dsoc = (di->dsoc + 1) * 1000 -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 						MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 	if (voltage_avg < pwroff_vol - 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 		if (!di->shtd_drop_sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 			di->shtd_drop_sec = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 		if (base2sec(di->shtd_drop_sec) > WAIT_SHTD_DROP_SEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 			BAT_INFO("voltage extreme low...soc:%d->0\n", di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 			di->shtd_drop_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 			di->dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 		di->shtd_drop_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 	DBG("ZERO-new: org_linek=%d, zero_linek=%d, dsoc=%d, Xsoc=%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 	    "rsoc=%d, gap=%d, v=%d, vsys=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 	    "ZERO-new: di->zero_dsoc=%d, zero_remain_cap=%d, zero_drop=%ld, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 	    "sht_drop=%ld\n\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 	    org_linek, di->zero_linek, di->dsoc, xsoc, di->rsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 	    min_gap_xsoc, voltage_avg, vsys, di->zero_dsoc, di->zero_remain_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 	    base2sec(di->zero_drop_sec), base2sec(di->shtd_drop_sec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) static void rk818_bat_finish_algo_prepare(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 	di->finish_base = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 	if (!di->finish_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 		di->finish_base = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) static void rk818_bat_smooth_algo_prepare(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 	int tmp_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 	tmp_soc = di->sm_chrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 	if (tmp_soc != di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 		di->sm_chrg_dsoc = di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 	tmp_soc = di->sm_dischrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 	if (tmp_soc != di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 		di->sm_dischrg_dsoc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 		(di->dsoc + 1) * 1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 	DBG("<%s>. tmp_soc=%d, dsoc=%d, dsoc:sm_dischrg=%d, sm_chrg=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 	    __func__, tmp_soc, di->dsoc, di->sm_dischrg_dsoc, di->sm_chrg_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 	rk818_bat_calc_sm_linek(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) static void rk818_bat_zero_algo_prepare(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	int tmp_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 	di->zero_timeout_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 	tmp_dsoc = di->zero_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	if (tmp_dsoc != di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 		di->zero_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	DBG("<%s>. first calc, reinit linek\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 	rk818_bat_calc_zero_linek(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) static void rk818_bat_calc_zero_algorithm(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	int tmp_soc = 0, sm_delta_dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 	tmp_soc = di->zero_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	if (tmp_soc == di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 	DBG("<%s>. enter: dsoc=%d, rsoc=%d\n", __func__, di->dsoc, di->rsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	/* when discharge slow down, take sm chrg into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 	if (di->dsoc < di->rsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 		/* take sm charge rest into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 		tmp_soc = di->sm_chrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 		if (tmp_soc == di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 			sm_delta_dsoc = di->sm_chrg_dsoc - di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 			di->sm_chrg_dsoc = di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 			di->zero_dsoc += sm_delta_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 			DBG("ZERO1: take sm chrg,delta=%d\n", sm_delta_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 	/* when discharge speed up, take sm dischrg into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 	if (di->dsoc > di->rsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 		/* take sm discharge rest into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 		tmp_soc = di->sm_dischrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 		if (tmp_soc == di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 			sm_delta_dsoc = di->sm_dischrg_dsoc -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 				((di->dsoc + 1) * 1000 - MIN_ACCURACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 			di->sm_dischrg_dsoc = (di->dsoc + 1) * 1000 -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 								MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 			di->zero_dsoc += sm_delta_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 			DBG("ZERO1: take sm dischrg,delta=%d\n", sm_delta_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 	/* check overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 	if (di->zero_dsoc > (di->dsoc + 1) * 1000 - MIN_ACCURACY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 		DBG("ZERO1: zero dsoc overflow: %d\n", di->zero_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 		di->zero_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 	/* check new dsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 	tmp_soc = di->zero_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 	if (tmp_soc != di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 		/* avoid dsoc jump when heavy load */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 		if ((di->dsoc - tmp_soc) > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 			di->dsoc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 			di->zero_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 			DBG("ZERO1: heavy load...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 			di->dsoc = tmp_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 		di->zero_drop_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 	DBG("ZERO1: zero_dsoc(Y0)=%d, dsoc=%d, rsoc=%d, tmp_soc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 	    di->zero_dsoc, di->dsoc, di->rsoc, tmp_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 	DBG("ZERO1: sm_dischrg_dsoc=%d, sm_chrg_dsoc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 	    di->sm_dischrg_dsoc, di->sm_chrg_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) static void rk818_bat_zero_algorithm(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 	int delta_cap = 0, delta_soc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 	di->zero_timeout_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 	delta_cap = di->zero_remain_cap - di->remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 	delta_soc = di->zero_linek * (delta_cap * 100) / DIV(di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 	DBG("ZERO1: zero_linek=%d, zero_dsoc(Y0)=%d, dsoc=%d, rsoc=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 	    "ZERO1: delta_soc(X0)=%d, delta_cap=%d, zero_remain_cap = %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 	    "ZERO1: timeout_cnt=%d, sm_dischrg=%d, sm_chrg=%d\n\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 	    di->zero_linek, di->zero_dsoc, di->dsoc, di->rsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 	    delta_soc, delta_cap, di->zero_remain_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 	    di->zero_timeout_cnt, di->sm_dischrg_dsoc, di->sm_chrg_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 	if ((delta_soc >= MIN_ZERO_DSOC_ACCURACY) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 	    (di->zero_timeout_cnt > MIN_ZERO_OVERCNT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 	    (di->zero_linek == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 		DBG("ZERO1:--------- enter calc -----------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 		di->zero_timeout_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 		di->zero_dsoc -= delta_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 		rk818_bat_calc_zero_algorithm(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 		rk818_bat_calc_zero_linek(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) static void rk818_bat_dump_time_table(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 	u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 	static int old_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	static int old_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	int mod = di->dsoc % 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 	int index = di->dsoc / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 	u32 time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 	if (rk818_bat_chrg_online(di))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 		time = base2min(di->plug_in_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 		time = base2min(di->plug_out_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 	if ((mod == 0) && (index > 0) && (old_index != index)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 		di->dbg_chrg_min[index - 1] = time - old_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 		old_min = time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 		old_index = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 	for (i = 1; i < 11; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 		DBG("Time[%d]=%d, ", (i * 10), di->dbg_chrg_min[i - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 	DBG("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) static void rk818_bat_debug_info(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 	u8 sup_tst, ggcon, ggsts, vb_mod, ts_ctrl, reboot_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 	u8 usb_ctrl, chrg_ctrl1, thermal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 	u8 int_sts1, int_sts2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 	u8 int_msk1, int_msk2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 	u8 chrg_ctrl2, chrg_ctrl3, rtc, misc, dcdc_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 	char *work_mode[] = {"ZERO", "FINISH", "UN", "UN", "SMOOTH"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 	char *bat_mode[] = {"BAT", "VIRTUAL"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 	if (rk818_bat_chrg_online(di))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 		di->plug_out_base = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 		di->plug_in_base = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 	rk818_bat_dump_time_table(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 	if (!dbg_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 	ts_ctrl = rk818_bat_read(di, RK818_TS_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 	misc = rk818_bat_read(di, RK818_MISC_MARK_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 	ggcon = rk818_bat_read(di, RK818_GGCON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 	ggsts = rk818_bat_read(di, RK818_GGSTS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 	sup_tst = rk818_bat_read(di, RK818_SUP_STS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 	vb_mod = rk818_bat_read(di, RK818_VB_MON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 	usb_ctrl = rk818_bat_read(di, RK818_USB_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 	chrg_ctrl1 = rk818_bat_read(di, RK818_CHRG_CTRL_REG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 	chrg_ctrl2 = rk818_bat_read(di, RK818_CHRG_CTRL_REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 	chrg_ctrl3 = rk818_bat_read(di, RK818_CHRG_CTRL_REG3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 	rtc = rk818_bat_read(di, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 	thermal = rk818_bat_read(di, RK818_THERMAL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 	int_sts1 = rk818_bat_read(di, RK818_INT_STS_REG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 	int_sts2 = rk818_bat_read(di, RK818_INT_STS_REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 	int_msk1 = rk818_bat_read(di, RK818_INT_STS_MSK_REG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 	int_msk2 = rk818_bat_read(di, RK818_INT_STS_MSK_REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 	dcdc_en = rk818_bat_read(di, RK818_DCDC_EN_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 	reboot_cnt = rk818_bat_read(di, RK818_REBOOT_CNT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 	DBG("\n------- DEBUG REGS, [Ver: %s] -------------------\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 	    "GGCON=0x%2x, GGSTS=0x%2x, RTC=0x%2x, DCDC_EN2=0x%2x\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 	    "SUP_STS= 0x%2x, VB_MOD=0x%2x, USB_CTRL=0x%2x\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 	    "THERMAL=0x%2x, MISC_MARK=0x%2x, TS_CTRL=0x%2x\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 	    "CHRG_CTRL:REG1=0x%2x, REG2=0x%2x, REG3=0x%2x\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 	    "INT_STS:  REG1=0x%2x, REG2=0x%2x\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 	    "INT_MSK:  REG1=0x%2x, REG2=0x%2x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 	    DRIVER_VERSION, ggcon, ggsts, rtc, dcdc_en,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 	    sup_tst, vb_mod, usb_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 	    thermal, misc, ts_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 	    chrg_ctrl1, chrg_ctrl2, chrg_ctrl3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 	    int_sts1, int_sts2, int_msk1, int_msk2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 	   );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 	DBG("###############################################################\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 	    "Dsoc=%d, Rsoc=%d, Vavg=%d, Iavg=%d, Cap=%d, Fcc=%d, d=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 	    "K=%d, Mode=%s, Oldcap=%d, Is=%d, Ip=%d, Vs=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 	    "fb_temp=%d, bat_temp=%d, sample_res=%d, USB=%d, DC=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 	    "off:i=0x%x, c=0x%x, p=%d, Rbat=%d, age_ocv_cap=%d, fb=%d, hot=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 	    "adp:finish=%lu, boot_min=%lu, sleep_min=%lu, adc=%d, Vsys=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 	    "bat:%s, meet: soc=%d, calc: dsoc=%d, rsoc=%d, Vocv=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 	    "pwr: dsoc=%d, rsoc=%d, vol=%d, halt: st=%d, cnt=%d, reboot=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 	    "ocv_c=%d: %d -> %d; max_c=%d: %d -> %d; force_c=%d: %d -> %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 	    "min=%d, init=%d, sw=%d, below0=%d, first=%d, changed=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 	    "###############################################################\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 	    di->dsoc, di->rsoc, di->voltage_avg, di->current_avg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 	    di->remain_cap, di->fcc, di->rsoc - di->dsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 	    di->sm_linek, work_mode[di->work_mode], di->sm_remain_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 	    di->res_div * chrg_cur_sel_array[chrg_ctrl1 & 0x0f],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 	    chrg_cur_input_array[usb_ctrl & 0x0f],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 	    chrg_vol_sel_array[(chrg_ctrl1 & 0x70) >> 4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 	    feedback_temp_array[(thermal & 0x0c) >> 2], di->temperature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 	    di->pdata->sample_res, di->usb_in, di->ac_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 	    rk818_bat_get_ioffset(di),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 	    rk818_bat_get_coffset(di), di->poffset, di->bat_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 	    di->age_adjust_cap, di->fb_blank, !!(thermal & HOTDIE_STS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	    base2min(di->finish_base),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 	    base2min(di->boot_base), di->sleep_sum_sec / 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 	    di->adc_allow_update,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 	    di->voltage_avg + di->current_avg * DEF_PWRPATH_RES / 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 	    bat_mode[di->pdata->bat_mode], di->dbg_meet_soc, di->dbg_calc_dsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 	    di->dbg_calc_rsoc, di->voltage_ocv, di->dbg_pwr_dsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 	    di->dbg_pwr_rsoc, di->dbg_pwr_vol, di->is_halt, di->halt_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 	    reboot_cnt, di->is_ocv_calib, di->ocv_pre_dsoc, di->ocv_new_dsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 	    di->is_max_soc_offset, di->max_pre_dsoc, di->max_new_dsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 	    di->is_force_calib, di->force_pre_dsoc, di->force_new_dsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 	    di->pwroff_min, di->is_initialized, di->is_sw_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 	    di->dbg_cap_low0, di->is_first_on, di->last_dsoc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 	   );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) static void rk818_bat_init_capacity(struct rk818_battery *di, u32 cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 	int delta_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 	delta_cap = cap - di->remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 	if (!delta_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 	di->age_adjust_cap += delta_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 	rk818_bat_init_coulomb_cap(di, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 	rk818_bat_smooth_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	rk818_bat_zero_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) static void rk818_bat_update_age_fcc(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 	int fcc, remain_cap, age_keep_min, lock_fcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 	lock_fcc = rk818_bat_get_coulomb_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 	remain_cap = lock_fcc - di->age_ocv_cap - di->age_adjust_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 	age_keep_min = base2min(di->age_keep_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 	DBG("%s: lock_fcc=%d, age_ocv_cap=%d, age_adjust_cap=%d, remain_cap=%d,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 	    "age_allow_update=%d, age_keep_min=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 	    __func__, lock_fcc, di->age_ocv_cap, di->age_adjust_cap, remain_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 	    di->age_allow_update, age_keep_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 	if ((di->chrg_status == CHARGE_FINISH) && (di->age_allow_update) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 	    (age_keep_min < 1200)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 		di->age_allow_update = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 		fcc = remain_cap * 100 / DIV(100 - di->age_ocv_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 		BAT_INFO("lock_fcc=%d, calc_cap=%d, age: soc=%d, cap=%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 			 "level=%d, fcc:%d->%d?\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 			 lock_fcc, remain_cap, di->age_ocv_soc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 			 di->age_ocv_cap, di->age_level, di->fcc, fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 		if ((fcc < di->qmax) && (fcc > MIN_FCC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 			BAT_INFO("fcc:%d->%d!\n", di->fcc, fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 			di->fcc = fcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 			rk818_bat_init_capacity(di, di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 			rk818_bat_save_fcc(di, di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 			rk818_bat_save_age_level(di, di->age_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) static void rk818_bat_wait_finish_sig(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 	int chrg_finish_vol = di->pdata->max_chrg_voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 	if (!rk818_bat_chrg_online(di))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 	if ((di->chrg_status == CHARGE_FINISH) && (di->adc_allow_update) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 	    (di->voltage_avg > chrg_finish_vol - 150)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 		rk818_bat_update_age_fcc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 		if (rk818_bat_adc_calib(di))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 			di->adc_allow_update = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) static void rk818_bat_finish_algorithm(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	unsigned long finish_sec, soc_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 	int plus_soc, finish_current, rest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 	/* rsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 	if ((di->remain_cap != di->fcc) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 	    (rk818_bat_get_chrg_status(di) == CHARGE_FINISH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 		di->age_adjust_cap += (di->fcc - di->remain_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 		rk818_bat_init_coulomb_cap(di, di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 	/* dsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 	if (di->dsoc < 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 		if (!di->finish_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 			di->finish_base = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 		finish_current = (di->rsoc - di->dsoc) >  FINISH_MAX_SOC_DELAY ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 					FINISH_CHRG_CUR2 : FINISH_CHRG_CUR1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 		finish_sec = base2sec(di->finish_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 		soc_sec = di->fcc * 3600 / 100 / DIV(finish_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 		plus_soc = finish_sec / DIV(soc_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 		if (finish_sec > soc_sec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 			rest = finish_sec % soc_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 			di->dsoc += plus_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 			di->finish_base = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 			if (di->finish_base > rest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 				di->finish_base = get_boot_sec() - rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 		DBG("<%s>.CHARGE_FINISH:dsoc<100,dsoc=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 		    "soc_time=%lu, sec_finish=%lu, plus_soc=%d, rest=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 		    __func__, di->dsoc, soc_sec, finish_sec, plus_soc, rest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) static void rk818_bat_calc_smooth_dischrg(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 	int tmp_soc = 0, sm_delta_dsoc = 0, zero_delta_dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 	tmp_soc = di->sm_dischrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 	if (tmp_soc == di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 	DBG("<%s>. enter: dsoc=%d, rsoc=%d\n", __func__, di->dsoc, di->rsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 	/* when dischrge slow down, take sm charge rest into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 	if (di->dsoc < di->rsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 		tmp_soc = di->sm_chrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 		if (tmp_soc == di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 			sm_delta_dsoc = di->sm_chrg_dsoc - di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 			di->sm_chrg_dsoc = di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 			di->sm_dischrg_dsoc += sm_delta_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 			DBG("<%s>. take sm dischrg, delta=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 			    __func__, sm_delta_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 	/* when discharge speed up, take zero discharge rest into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 	if (di->dsoc > di->rsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 		tmp_soc = di->zero_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 		if (tmp_soc == di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 			zero_delta_dsoc = di->zero_dsoc - ((di->dsoc + 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 						1000 - MIN_ACCURACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 			di->zero_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 			di->sm_dischrg_dsoc += zero_delta_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 			DBG("<%s>. take zero schrg, delta=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 			    __func__, zero_delta_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 	/* check up overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 	if ((di->sm_dischrg_dsoc) > ((di->dsoc + 1) * 1000 - MIN_ACCURACY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 		DBG("<%s>. dischrg_dsoc up overflow\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 		di->sm_dischrg_dsoc = (di->dsoc + 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 					1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 	/* check new dsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 	tmp_soc = di->sm_dischrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 	if (tmp_soc != di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 		di->dsoc = tmp_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 		di->sm_chrg_dsoc = di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 	DBG("<%s>. dsoc=%d, rsoc=%d, dsoc:sm_dischrg=%d, sm_chrg=%d, zero=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 	    __func__, di->dsoc, di->rsoc, di->sm_dischrg_dsoc, di->sm_chrg_dsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 	    di->zero_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) static void rk818_bat_calc_smooth_chrg(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 	int tmp_soc = 0, sm_delta_dsoc = 0, zero_delta_dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 	tmp_soc = di->sm_chrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 	if (tmp_soc == di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 	DBG("<%s>. enter: dsoc=%d, rsoc=%d\n", __func__, di->dsoc, di->rsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 	/* when charge slow down, take zero & sm dischrg into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 	if (di->dsoc > di->rsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 		/* take sm discharge rest into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 		tmp_soc = di->sm_dischrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 		if (tmp_soc == di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 			sm_delta_dsoc = di->sm_dischrg_dsoc -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 					((di->dsoc + 1) * 1000 - MIN_ACCURACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 			di->sm_dischrg_dsoc = (di->dsoc + 1) * 1000 -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 							MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 			di->sm_chrg_dsoc += sm_delta_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 			DBG("<%s>. take sm dischrg, delta=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 			   __func__, sm_delta_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 		/* take zero discharge rest into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 		tmp_soc = di->zero_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 		if (tmp_soc == di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 			zero_delta_dsoc = di->zero_dsoc -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 			((di->dsoc + 1) * 1000 - MIN_ACCURACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 			di->zero_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 			di->sm_chrg_dsoc += zero_delta_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 			DBG("<%s>. take zero dischrg, delta=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 			    __func__, zero_delta_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 	/* check down overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 	if (di->sm_chrg_dsoc < di->dsoc * 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 		DBG("<%s>. chrg_dsoc down overflow\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 		di->sm_chrg_dsoc = di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 	/* check new dsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 	tmp_soc = di->sm_chrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 	if (tmp_soc != di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 		di->dsoc = tmp_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 		di->sm_dischrg_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 	DBG("<%s>.dsoc=%d, rsoc=%d, dsoc: sm_dischrg=%d, sm_chrg=%d, zero=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 	    __func__, di->dsoc, di->rsoc, di->sm_dischrg_dsoc, di->sm_chrg_dsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 	    di->zero_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) static void rk818_bat_smooth_algorithm(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 	int ydsoc = 0, delta_cap = 0, old_cap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 	unsigned long tgt_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 	di->remain_cap = rk818_bat_get_coulomb_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 	/* full charge: slow down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 	if ((di->dsoc == 99) && (di->chrg_status == CC_OR_CV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 	    (di->current_avg > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 		di->sm_linek = FULL_CHRG_K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 	/* terminal charge, slow down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 	} else if ((di->current_avg >= TERM_CHRG_CURR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 	    (di->chrg_status == CC_OR_CV) && (di->dsoc >= TERM_CHRG_DSOC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 		di->sm_linek = TERM_CHRG_K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 		DBG("<%s>. terminal mode..\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 	/* simulate charge, speed up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 	} else if ((di->current_avg <= SIMULATE_CHRG_CURR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 		   (di->current_avg > 0) && (di->chrg_status == CC_OR_CV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 		   (di->dsoc < TERM_CHRG_DSOC) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 		   ((di->rsoc - di->dsoc) >= SIMULATE_CHRG_INTV)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 		di->sm_linek = SIMULATE_CHRG_K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 		DBG("<%s>. simulate mode..\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 		/* charge and discharge switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 		if ((di->sm_linek * di->current_avg <= 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 		    (di->sm_linek == TERM_CHRG_K) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 		    (di->sm_linek == FULL_CHRG_K) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 		    (di->sm_linek == SIMULATE_CHRG_K)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 			DBG("<%s>. linek mode, retinit sm linek..\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 			rk818_bat_calc_sm_linek(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 	old_cap = di->sm_remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 	 * when dsoc equal rsoc(not include full, term, simulate case),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 	 * sm_linek should change to -1000/1000 smoothly to avoid dsoc+1/-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 	 * right away, so change it after flat seconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 	if ((di->dsoc == di->rsoc) && (abs(di->sm_linek) != 1000) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 	    (di->sm_linek != FULL_CHRG_K && di->sm_linek != TERM_CHRG_K &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 	     di->sm_linek != SIMULATE_CHRG_K)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 		if (!di->flat_match_sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 			di->flat_match_sec = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 		tgt_sec = di->fcc * 3600 / 100 / DIV(abs(di->current_avg)) / 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 		if (base2sec(di->flat_match_sec) >= tgt_sec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 			di->flat_match_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 			di->sm_linek = (di->current_avg >= 0) ? 1000 : -1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 		DBG("<%s>. flat_sec=%ld, tgt_sec=%ld, sm_k=%d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 		    base2sec(di->flat_match_sec), tgt_sec, di->sm_linek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 		di->flat_match_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 	/* abs(k)=1000 or dsoc=100, stop calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 	if ((abs(di->sm_linek) == 1000) || (di->current_avg >= 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 	     di->chrg_status == CC_OR_CV && di->dsoc >= 100)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 		DBG("<%s>. sm_linek=%d\n", __func__, di->sm_linek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 		if (abs(di->sm_linek) == 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 			di->dsoc = di->rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 			di->sm_linek = (di->sm_linek > 0) ? 1000 : -1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 			DBG("<%s>. dsoc == rsoc, sm_linek=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 			    __func__, di->sm_linek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 		di->sm_remain_cap = di->remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 		di->sm_chrg_dsoc = di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 		di->sm_dischrg_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 		DBG("<%s>. sm_dischrg_dsoc=%d, sm_chrg_dsoc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 		    __func__, di->sm_dischrg_dsoc, di->sm_chrg_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 		delta_cap = di->remain_cap - di->sm_remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 		if (delta_cap == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 			DBG("<%s>. delta_cap = 0\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 		ydsoc = di->sm_linek * abs(delta_cap) * 100 / DIV(di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 		if (ydsoc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 			DBG("<%s>. ydsoc = 0\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 		di->sm_remain_cap = di->remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 		DBG("<%s>. k=%d, ydsoc=%d; cap:old=%d, new:%d; delta_cap=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 		    __func__, di->sm_linek, ydsoc, old_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 		    di->sm_remain_cap, delta_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 		/* discharge mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 		if (ydsoc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 			di->sm_dischrg_dsoc += ydsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 			rk818_bat_calc_smooth_dischrg(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 		/* charge mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 			di->sm_chrg_dsoc += ydsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 			rk818_bat_calc_smooth_chrg(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 		if (di->s2r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 			di->s2r = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 			rk818_bat_calc_sm_linek(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331)  * cccv and finish switch all the time will cause dsoc freeze,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332)  * if so, do finish chrg, 100ma is less than min finish_ma.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) static bool rk818_bat_fake_finish_mode(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 	if ((di->rsoc == 100) && (rk818_bat_get_chrg_status(di) == CC_OR_CV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 	    (abs(di->current_avg) <= 100))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) static void rk818_bat_display_smooth(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 	/* discharge: reinit "zero & smooth" algorithm to avoid handling dsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 	if (di->s2r && !di->sleep_chrg_online) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 		DBG("s2r: discharge, reset algorithm...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 		di->s2r = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 		rk818_bat_zero_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 		rk818_bat_smooth_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 	if (di->work_mode == MODE_FINISH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 		DBG("step1: charge finish...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 		rk818_bat_finish_algorithm(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 		if ((rk818_bat_get_chrg_status(di) != CHARGE_FINISH) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 		    !rk818_bat_fake_finish_mode(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 			if ((di->current_avg < 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 			    (di->voltage_avg < di->pdata->zero_algorithm_vol)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 				DBG("step1: change to zero mode...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 				rk818_bat_zero_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 				di->work_mode = MODE_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 				DBG("step1: change to smooth mode...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 				rk818_bat_smooth_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 				di->work_mode = MODE_SMOOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 	} else if (di->work_mode == MODE_ZERO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 		DBG("step2: zero algorithm...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 		rk818_bat_zero_algorithm(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 		if ((di->voltage_avg >= di->pdata->zero_algorithm_vol + 50) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 		    (di->current_avg >= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 			DBG("step2: change to smooth mode...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 			rk818_bat_smooth_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 			di->work_mode = MODE_SMOOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 		} else if ((rk818_bat_get_chrg_status(di) == CHARGE_FINISH) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 			   rk818_bat_fake_finish_mode(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 			DBG("step2: change to finish mode...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 			rk818_bat_finish_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 			di->work_mode = MODE_FINISH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 		DBG("step3: smooth algorithm...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 		rk818_bat_smooth_algorithm(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 		if ((di->current_avg < 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 		    (di->voltage_avg < di->pdata->zero_algorithm_vol)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 			DBG("step3: change to zero mode...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 			rk818_bat_zero_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 			di->work_mode = MODE_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 		} else if ((rk818_bat_get_chrg_status(di) == CHARGE_FINISH) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 			   rk818_bat_fake_finish_mode(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 			DBG("step3: change to finish mode...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 			rk818_bat_finish_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 			di->work_mode = MODE_FINISH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) static void rk818_bat_relax_vol_calib(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 	int soc, cap, vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 	vol = di->voltage_relax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 	soc = rk818_bat_vol_to_ocvsoc(di, vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 	cap = rk818_bat_vol_to_ocvcap(di, vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 	rk818_bat_init_capacity(di, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 	BAT_INFO("sleep ocv calib: rsoc=%d, cap=%d\n", soc, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) static void rk818_bat_relife_age_flag(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 	u8 ocv_soc, ocv_cap, soc_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 	if (di->voltage_relax <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 	ocv_soc = rk818_bat_vol_to_ocvsoc(di, di->voltage_relax);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 	ocv_cap = rk818_bat_vol_to_ocvcap(di, di->voltage_relax);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 	DBG("<%s>. ocv_soc=%d, min=%lu, vol=%d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 	    ocv_soc, di->sleep_dischrg_sec / 60, di->voltage_relax);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 	/* sleep enough time and ocv_soc enough low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 	if (!di->age_allow_update && ocv_soc <= 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 		di->age_voltage = di->voltage_relax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 		di->age_ocv_cap = ocv_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 		di->age_ocv_soc = ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 		di->age_adjust_cap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 		if (ocv_soc <= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 			di->age_level = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 		else if (ocv_soc < 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 			di->age_level = 90;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 			di->age_level = 80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 		soc_level = rk818_bat_get_age_level(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 		if (soc_level > di->age_level) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 			di->age_allow_update = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 			di->age_allow_update = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 			di->age_keep_sec = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 		BAT_INFO("resume: age_vol:%d, age_ocv_cap:%d, age_ocv_soc:%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 			 "soc_level:%d, age_allow_update:%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 			 "age_level:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 			 di->age_voltage, di->age_ocv_cap, ocv_soc, soc_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 			 di->age_allow_update, di->age_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) static int rk818_bat_sleep_dischrg(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 	bool ocv_soc_updated = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 	int tgt_dsoc, gap_soc, sleep_soc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 	int pwroff_vol = di->pdata->pwroff_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 	unsigned long sleep_sec = di->sleep_dischrg_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 	DBG("<%s>. enter: dsoc=%d, rsoc=%d, rv=%d, v=%d, sleep_min=%lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 	    __func__, di->dsoc, di->rsoc, di->voltage_relax,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 	    di->voltage_avg, sleep_sec / 60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 	if (di->voltage_relax >= di->voltage_avg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 		rk818_bat_relax_vol_calib(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 		rk818_bat_restart_relax(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 		rk818_bat_relife_age_flag(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 		ocv_soc_updated = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 	/* handle dsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 	if (di->dsoc <= di->rsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 		di->sleep_sum_cap = (SLP_CURR_MIN * sleep_sec / 3600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 		sleep_soc = di->sleep_sum_cap * 100 / DIV(di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 		tgt_dsoc = di->dsoc - sleep_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 		if (sleep_soc > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 			BAT_INFO("calib0: rl=%d, dl=%d, intval=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 				 di->rsoc, di->dsoc, sleep_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 			if (di->dsoc < 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 				di->dsoc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 			} else if ((tgt_dsoc < 5) && (di->dsoc >= 5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 				if (di->dsoc == 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 					di->dsoc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 					di->dsoc = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 			} else if (tgt_dsoc > 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 				di->dsoc = tgt_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 		DBG("%s: dsoc<=rsoc, sum_cap=%d==>sleep_soc=%d, tgt_dsoc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 		    __func__, di->sleep_sum_cap, sleep_soc, tgt_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 		/* di->dsoc > di->rsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 		di->sleep_sum_cap = (SLP_CURR_MAX * sleep_sec / 3600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 		sleep_soc = di->sleep_sum_cap / DIV(di->fcc / 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 		gap_soc = di->dsoc - di->rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 		BAT_INFO("calib1: rsoc=%d, dsoc=%d, intval=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 			 di->rsoc, di->dsoc, sleep_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 		if (gap_soc > sleep_soc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 			if ((gap_soc - 5) > (sleep_soc * 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 				di->dsoc -= (sleep_soc * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 				di->dsoc -= sleep_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 			di->dsoc = di->rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 		DBG("%s: dsoc>rsoc, sum_cap=%d=>sleep_soc=%d, gap_soc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 		    __func__, di->sleep_sum_cap, sleep_soc, gap_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 	if (di->voltage_avg <= pwroff_vol - 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 		di->dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 		rk_send_wakeup_key();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 		BAT_INFO("low power sleeping, shutdown... %d\n", di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 	if (ocv_soc_updated && sleep_soc && (di->rsoc - di->dsoc) < 5 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 	    di->dsoc < 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 		di->dsoc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 		BAT_INFO("low power sleeping, reserved... %d\n", di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 	if (di->dsoc <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 		di->dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 		rk_send_wakeup_key();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 		BAT_INFO("sleep dsoc is %d...\n", di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 	DBG("<%s>. out: dsoc=%d, rsoc=%d, sum_cap=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 	    __func__, di->dsoc, di->rsoc, di->sleep_sum_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 	return sleep_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) static void rk818_bat_power_supply_changed(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 	u8 status, thermal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 	static int old_soc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 	if (di->dsoc > 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 		di->dsoc = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 	else if (di->dsoc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 		di->dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 	if (di->dsoc == old_soc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 	thermal = rk818_bat_read(di, RK818_THERMAL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 	status = rk818_bat_read(di, RK818_SUP_STS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 	status = (status & CHRG_STATUS_MSK) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 	old_soc = di->dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 	di->last_dsoc = di->dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 	power_supply_changed(di->bat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 	BAT_INFO("changed: dsoc=%d, rsoc=%d, v=%d, ov=%d c=%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 		 "cap=%d, f=%d, st=%s, hotdie=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 		 di->dsoc, di->rsoc, di->voltage_avg, di->voltage_ocv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 		 di->current_avg, di->remain_cap, di->fcc, bat_status[status],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 		 !!(thermal & HOTDIE_STS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 	BAT_INFO("dl=%d, rl=%d, v=%d, halt=%d, halt_n=%d, max=%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 		 "init=%d, sw=%d, calib=%d, below0=%d, force=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 		 di->dbg_pwr_dsoc, di->dbg_pwr_rsoc, di->dbg_pwr_vol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 		 di->is_halt, di->halt_cnt, di->is_max_soc_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 		 di->is_initialized, di->is_sw_reset, di->is_ocv_calib,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 		 di->dbg_cap_low0, di->is_force_calib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) static u8 rk818_bat_check_reboot(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 	u8 cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 	cnt = rk818_bat_read(di, RK818_REBOOT_CNT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 	cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 	if (cnt >= REBOOT_MAX_CNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 		BAT_INFO("reboot: %d --> %d\n", di->dsoc, di->rsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 		di->dsoc = di->rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 		if (di->dsoc > 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 			di->dsoc = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 		else if (di->dsoc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 			di->dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 		rk818_bat_save_dsoc(di, di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 		cnt = REBOOT_MAX_CNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 	rk818_bat_save_reboot_cnt(di, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 	DBG("reboot cnt: %d\n", cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 	return cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) static void rk818_bat_rsoc_daemon(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 	int est_vol, remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 	static unsigned long sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	if ((di->remain_cap < 0) && (di->fb_blank != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 		if (!sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 			sec = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 		wake_lock_timeout(&di->wake_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 				  (di->pdata->monitor_sec + 1) * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 		DBG("sec=%ld, hold_sec=%ld\n", sec, base2sec(sec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 		if (base2sec(sec) >= 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 			sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 			di->dbg_cap_low0++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 			est_vol = di->voltage_avg -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 					(di->bat_res * di->current_avg) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 			remain_cap = rk818_bat_vol_to_ocvcap(di, est_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 			rk818_bat_init_capacity(di, remain_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 			BAT_INFO("adjust cap below 0 --> %d, rsoc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 				 di->remain_cap, di->rsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 			wake_unlock(&di->wake_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 		sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) static void rk818_bat_update_info(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 	int is_charging;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 	di->voltage_avg = rk818_bat_get_avg_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 	di->current_avg = rk818_bat_get_avg_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 	di->voltage_relax = rk818_bat_get_relax_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 	di->rsoc = rk818_bat_get_rsoc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 	di->remain_cap = rk818_bat_get_coulomb_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 	di->chrg_status = rk818_bat_get_chrg_status(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 	is_charging = rk818_bat_get_charge_state(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 	if (is_charging != di->is_charging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 		di->is_charging = is_charging;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 		if (is_charging)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 			di->charge_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 	if (di->voltage_avg > di->voltage_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 		di->voltage_max = di->voltage_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 	if (di->current_avg > di->current_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 		di->current_max = di->current_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 	/* smooth charge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 	if (di->remain_cap > di->fcc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 		di->sm_remain_cap -= (di->remain_cap - di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 		DBG("<%s>. cap: remain=%d, sm_remain=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 		    __func__, di->remain_cap, di->sm_remain_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 		rk818_bat_init_coulomb_cap(di, di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 	if (di->chrg_status != CHARGE_FINISH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 		di->finish_base = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 	 * we need update fcc in continuous charging state, if discharge state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 	 * keep at least 2 hour, we decide not to update fcc, so clear the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 	 * fcc update flag: age_allow_update.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 	if (base2min(di->plug_out_base) > 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 		di->age_allow_update = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 	/* do adc calib: status must from cccv mode to finish mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 	if (di->chrg_status == CC_OR_CV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 		di->adc_allow_update = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 		di->adc_calib_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) static void rk818_bat_init_ts1_detect(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 	u32 *ntc_table = di->pdata->ntc_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 	if (!di->pdata->ntc_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 	/* select ua */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 	buf = rk818_bat_read(di, RK818_TS_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 	buf &= ~TS1_CUR_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 	/* chose suitable UA for temperature detect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 	if (ntc_table[0] < NTC_80UA_MAX_MEASURE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 		di->pdata->ntc_factor = NTC_CALC_FACTOR_80UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 		di->pdata->ntc_uA = 80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 		buf |= ADC_CUR_80UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 	} else if (ntc_table[0] < NTC_60UA_MAX_MEASURE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 		di->pdata->ntc_factor = NTC_CALC_FACTOR_60UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 		di->pdata->ntc_uA = 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 		buf |= ADC_CUR_60UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 	} else if (ntc_table[0] < NTC_40UA_MAX_MEASURE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 		di->pdata->ntc_factor = NTC_CALC_FACTOR_40UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 		di->pdata->ntc_uA = 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 		buf |= ADC_CUR_40UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 		di->pdata->ntc_factor = NTC_CALC_FACTOR_20UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 		di->pdata->ntc_uA = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 		buf |= ADC_CUR_20UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 	rk818_bat_write(di, RK818_TS_CTRL_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 	/* enable ADC_TS1_EN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 	buf = rk818_bat_read(di, RK818_ADC_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 	buf |= ADC_TS1_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 	rk818_bat_write(di, RK818_ADC_CTRL_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709)  * Due to hardware design issue, Vdelta = "(R_sample + R_other) * I_avg" will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710)  * included into TS1 adc value. We must subtract it to get correct adc value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711)  * The solution:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713)  * (1) calculate Vdelta:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715)  *   adc1 - Vdelta    ua1			  (adc2 * ua1) - (adc1 * ua2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716)  *   ------------- = -----  ==> equals: Vdelta = -----------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717)  *   adc2 - Vdelta    ua2				ua1 - ua2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720)  * (2) calculate correct ADC value:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722)  *     charging: ADC = adc1 - abs(Vdelta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723)  *  discharging: ADC = adc1 + abs(Vdelta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) static int rk818_bat_get_ntc_res(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 	int adc1 = 0, adc2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 	int ua1, ua2, v_delta, res, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 	/* read sample ua1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 	buf = rk818_bat_read(di, RK818_TS_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 	DBG("<%s>. read adc1, sample uA=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 	    __func__, ((buf & 0x03) + 1) * 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 	/* read adc adc1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 	ua1 = di->pdata->ntc_uA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 	adc1 |= rk818_bat_read(di, RK818_TS1_ADC_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 	adc1 |= rk818_bat_read(di, RK818_TS1_ADC_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 	/* chose reference UA for adc2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 	ua2 = (ua1 != 20) ? 20 : 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 	buf = rk818_bat_read(di, RK818_TS_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 	buf &= ~TS1_CUR_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 	buf |= ((ua2 - 20) / 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 	rk818_bat_write(di, RK818_TS_CTRL_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 	/* read adc adc2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 	msleep(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 	/* read sample ua2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 	buf = rk818_bat_read(di, RK818_TS_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 	DBG("<%s>. read adc2, sample uA=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 	    __func__, ((buf & 0x03) + 1) * 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 	adc2 |= rk818_bat_read(di, RK818_TS1_ADC_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 	adc2 |= rk818_bat_read(di, RK818_TS1_ADC_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 	DBG("<%s>. ua1=%d, ua2=%d, adc1=%d, adc2=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 	    __func__, ua1, ua2, adc1, adc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 	/* calculate delta voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 	if (adc2 != adc1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 		v_delta = abs((adc2 * ua1 - adc1 * ua2) / (ua2 - ua1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 		v_delta = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 	/* considering current avg direction, calcuate real adc value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 	val = (di->current_avg >= 0) ? (adc1 - v_delta) : (adc1 + v_delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 	DBG("<%s>. Iavg=%d, Vdelta=%d, Vadc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 	    __func__, di->current_avg, v_delta, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 	res = val * di->pdata->ntc_factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 	DBG("<%s>. val=%d, ntc_res=%d, ntc_factor=%d, Rdelta=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 	    __func__, val, res, di->pdata->ntc_factor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 	    v_delta * di->pdata->ntc_factor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 	DBG("<%s>. t=[%d'C(%d) ~ %dC(%d)]\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 	    di->pdata->ntc_degree_from, di->pdata->ntc_table[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 	    di->pdata->ntc_degree_from + di->pdata->ntc_size - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 	    di->pdata->ntc_table[di->pdata->ntc_size - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 	rk818_bat_init_ts1_detect(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) static void rk818_bat_set_input_current(struct rk818_battery *di,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 					int input_current)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 	u8 usb_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 	usb_ctrl = rk818_bat_read(di, RK818_USB_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 	usb_ctrl &= ~0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 	usb_ctrl |= (input_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 	rk818_bat_write(di, RK818_USB_CTRL_REG, usb_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) static BLOCKING_NOTIFIER_HEAD(rk818_bat_notifier_chain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) int rk818_bat_temp_notifier_register(struct notifier_block *nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 	return blocking_notifier_chain_register(&rk818_bat_notifier_chain, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) EXPORT_SYMBOL_GPL(rk818_bat_temp_notifier_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) int rk818_bat_temp_notifier_unregister(struct notifier_block *nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 	return blocking_notifier_chain_unregister(&rk818_bat_notifier_chain, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) EXPORT_SYMBOL_GPL(rk818_bat_temp_notifier_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) static void rk818_bat_temp_notifier_callback(int temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 	blocking_notifier_call_chain(&rk818_bat_notifier_chain, temp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) static void rk818_bat_update_temperature(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 	static int old_temp, first_time = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 	u32 ntc_size, *ntc_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 	int i, res, temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 	ntc_table = di->pdata->ntc_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 	ntc_size = di->pdata->ntc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 	di->temperature = VIRTUAL_TEMPERATURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 	if (ntc_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 		res = rk818_bat_get_ntc_res(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 		if (res < ntc_table[ntc_size - 1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 			di->temperature = di->pdata->ntc_degree_from +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 					  di->pdata->ntc_size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 			if (di->pdata->bat_mode != MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 				rk818_bat_set_input_current(di, INPUT_CUR80MA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 			BAT_INFO("bat ntc upper max degree: R=%d\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 		} else if (res > ntc_table[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 			di->temperature = di->pdata->ntc_degree_from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 			if (di->pdata->bat_mode != MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 				rk818_bat_set_input_current(di, INPUT_CUR80MA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 			BAT_INFO("bat ntc lower min degree: R=%d\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 			for (i = 0; i < ntc_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 				if (res >= ntc_table[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 			/* if first in, init old_temp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 			temp = (i + di->pdata->ntc_degree_from) * 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 			if (first_time == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 				di->temperature = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 				old_temp = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 				first_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 			 * compare with old one, it's invalid when over 50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 			 * and we should use old data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 			if (abs(temp - old_temp) > 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 				temp = old_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 				old_temp = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 			di->temperature = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 			DBG("<%s>. temperature = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 			    __func__, di->temperature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 			rk818_bat_temp_notifier_callback(di->temperature / 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) static void rk818_bat_init_dsoc_algorithm(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 	int16_t rest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 	unsigned long soc_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 	const char *mode_name[] = { "MODE_ZERO", "MODE_FINISH",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 		"MODE_SMOOTH_CHRG", "MODE_SMOOTH_DISCHRG", "MODE_SMOOTH", };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 	/* get rest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 	rest |= rk818_bat_read(di, RK818_CALC_REST_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 	rest |= rk818_bat_read(di, RK818_CALC_REST_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 	/* get mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 	buf = rk818_bat_read(di, RK818_MISC_MARK_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 	di->algo_rest_mode = (buf & ALGO_REST_MODE_MSK) >> ALGO_REST_MODE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 	if (rk818_bat_get_chrg_status(di) == CHARGE_FINISH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 		if (di->algo_rest_mode == MODE_FINISH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 			soc_sec = di->fcc * 3600 / 100 / FINISH_CHRG_CUR1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 			if ((rest / DIV(soc_sec)) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 				if (di->dsoc < 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 					di->dsoc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 					di->algo_rest_val = rest % soc_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 					BAT_INFO("algorithm rest(%d) dsoc "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 						 "inc: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 						 rest, di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 					di->algo_rest_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 				di->algo_rest_val = rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 			di->algo_rest_val = rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 		/* charge speed up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 		if ((rest / 1000) > 0 && rk818_bat_chrg_online(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 			if (di->dsoc < di->rsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 				di->dsoc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 				di->algo_rest_val = rest % 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 				BAT_INFO("algorithm rest(%d) dsoc inc: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 					 rest, di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 				di->algo_rest_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 		/* discharge speed up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 		} else if (((rest / 1000) < 0) && !rk818_bat_chrg_online(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 			if (di->dsoc > di->rsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 				di->dsoc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 				di->algo_rest_val = rest % 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 				BAT_INFO("algorithm rest(%d) dsoc sub: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 					 rest, di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 				di->algo_rest_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 			di->algo_rest_val = rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 	if (di->dsoc >= 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 		di->dsoc = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 	else if (di->dsoc <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 		di->dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 	/* init current mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 	di->voltage_avg = rk818_bat_get_avg_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 	di->current_avg = rk818_bat_get_avg_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 	if (rk818_bat_get_chrg_status(di) == CHARGE_FINISH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 		rk818_bat_finish_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 		di->work_mode = MODE_FINISH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 		rk818_bat_smooth_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 		di->work_mode = MODE_SMOOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 	DBG("<%s>. init: org_rest=%d, rest=%d, mode=%s; "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 	    "doc(x1000): zero=%d, chrg=%d, dischrg=%d, finish=%lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 	    __func__, rest, di->algo_rest_val, mode_name[di->algo_rest_mode],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 	    di->zero_dsoc, di->sm_chrg_dsoc, di->sm_dischrg_dsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 	    di->finish_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) static void rk818_bat_save_algo_rest(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 	u8 buf, mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 	int16_t algo_rest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 	int tmp_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 	int zero_rest = 0, sm_chrg_rest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 	int sm_dischrg_rest = 0, finish_rest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 	const char *mode_name[] = { "MODE_ZERO", "MODE_FINISH",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 		"MODE_SMOOTH_CHRG", "MODE_SMOOTH_DISCHRG", "MODE_SMOOTH", };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 	/* zero dischrg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 	tmp_soc = (di->zero_dsoc) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 	if (tmp_soc == di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 		zero_rest = di->zero_dsoc - ((di->dsoc + 1) * 1000 -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) 				MIN_ACCURACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 	/* sm chrg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 	tmp_soc = di->sm_chrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 	if (tmp_soc == di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 		sm_chrg_rest = di->sm_chrg_dsoc - di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 	/* sm dischrg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 	tmp_soc = (di->sm_dischrg_dsoc) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 	if (tmp_soc == di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 		sm_dischrg_rest = di->sm_dischrg_dsoc - ((di->dsoc + 1) * 1000 -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 				MIN_ACCURACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 	/* last time is also finish chrg, then add last rest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 	if (di->algo_rest_mode == MODE_FINISH && di->algo_rest_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 		finish_rest = base2sec(di->finish_base) + di->algo_rest_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 		finish_rest = base2sec(di->finish_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 	/* total calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 	if ((rk818_bat_chrg_online(di) && (di->dsoc > di->rsoc)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 	    (!rk818_bat_chrg_online(di) && (di->dsoc < di->rsoc)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 	    (di->dsoc == di->rsoc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 		di->algo_rest_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 		algo_rest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 		DBG("<%s>. step1..\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 	} else if (di->work_mode == MODE_FINISH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 		algo_rest = finish_rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 		DBG("<%s>. step2..\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 	} else if (di->algo_rest_mode == MODE_FINISH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 		algo_rest = zero_rest + sm_dischrg_rest + sm_chrg_rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 		DBG("<%s>. step3..\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 		if (rk818_bat_chrg_online(di) && (di->dsoc < di->rsoc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 			algo_rest = sm_chrg_rest + di->algo_rest_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 		else if (!rk818_bat_chrg_online(di) && (di->dsoc > di->rsoc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 			algo_rest = zero_rest + sm_dischrg_rest +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 				    di->algo_rest_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 			algo_rest = zero_rest + sm_dischrg_rest + sm_chrg_rest +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 				    di->algo_rest_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 		DBG("<%s>. step4..\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 	/* check mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 	if ((di->work_mode == MODE_FINISH) || (di->work_mode == MODE_ZERO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 		mode = di->work_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 	} else {/* MODE_SMOOTH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 		if (di->sm_linek > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 			mode = MODE_SMOOTH_CHRG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 			mode = MODE_SMOOTH_DISCHRG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 	/* save mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 	buf = rk818_bat_read(di, RK818_MISC_MARK_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 	buf &= ~ALGO_REST_MODE_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 	buf |= (mode << ALGO_REST_MODE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 	rk818_bat_write(di, RK818_MISC_MARK_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 	/* save rest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 	buf = (algo_rest >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 	rk818_bat_write(di, RK818_CALC_REST_REGH, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 	buf = (algo_rest >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 	rk818_bat_write(di, RK818_CALC_REST_REGL, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 	DBG("<%s>. rest: algo=%d, mode=%s, last_rest=%d; zero=%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) 	    "chrg=%d, dischrg=%d, finish=%lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 	    __func__, algo_rest, mode_name[mode], di->algo_rest_val, zero_rest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 	    sm_chrg_rest, sm_dischrg_rest, base2sec(di->finish_base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) static void rk818_bat_save_data(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) 	rk818_bat_save_dsoc(di, di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 	rk818_bat_save_cap(di, di->remain_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) 	rk818_bat_save_algo_rest(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) static void rk818_battery_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 	struct rk818_battery *di =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 		container_of(work, struct rk818_battery, bat_delay_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 	rk818_bat_update_info(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 	rk818_bat_wait_finish_sig(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 	rk818_bat_rsoc_daemon(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 	rk818_bat_update_temperature(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 	rk818_bat_display_smooth(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 	rk818_bat_power_supply_changed(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 	rk818_bat_save_data(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 	rk818_bat_debug_info(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 	queue_delayed_work(di->bat_monitor_wq, &di->bat_delay_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 			   msecs_to_jiffies(di->monitor_ms));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) static irqreturn_t rk818_vb_low_irq(int irq, void *bat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 	struct rk818_battery *di = (struct rk818_battery *)bat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) 	di->dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 	rk_send_wakeup_key();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 	BAT_INFO("lower power yet, power off system! v=%d, c=%d, dsoc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 		 di->voltage_avg, di->current_avg, di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) static void rk818_bat_init_sysfs(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 	for (i = 0; i < ARRAY_SIZE(rk818_bat_attr); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 		ret = sysfs_create_file(&di->dev->kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 					&rk818_bat_attr[i].attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 			dev_err(di->dev, "create bat node(%s) error\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 				rk818_bat_attr[i].attr.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) static int rk818_bat_init_irqs(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 	struct rk808 *rk818 = di->rk818;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 	struct platform_device *pdev = di->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 	int ret, vb_lo_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 	vb_lo_irq = regmap_irq_get_virq(rk818->irq_data, RK818_IRQ_VB_LO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 	if (vb_lo_irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 		dev_err(di->dev, "vb_lo_irq request failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 		return vb_lo_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 	ret = devm_request_threaded_irq(di->dev, vb_lo_irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 					rk818_vb_low_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 					"rk818_vb_low", di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 		dev_err(&pdev->dev, "vb_lo_irq request failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 	enable_irq_wake(vb_lo_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) static void rk818_bat_init_info(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 	di->design_cap = di->pdata->design_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 	di->qmax = di->pdata->design_qmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 	di->bat_res = di->pdata->bat_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 	di->monitor_ms = di->pdata->monitor_sec * TIMER_MS_COUNTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 	di->boot_base = POWER_ON_SEC_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 	di->res_div = (di->pdata->sample_res == SAMPLE_RES_20MR) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 		       SAMPLE_RES_DIV1 : SAMPLE_RES_DIV2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) static time64_t rk818_get_rtc_sec(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 	struct rtc_time tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 	struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 	err = rtc_read_time(rtc, &tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 		dev_err(rtc->dev.parent, "read hardware clk failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 	err = rtc_valid_tm(&tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 		dev_err(rtc->dev.parent, "invalid date time\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 	return rtc_tm_to_time64(&tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) static int rk818_bat_rtc_sleep_sec(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 	int interval_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 	interval_sec = rk818_get_rtc_sec() - di->rtc_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 	return (interval_sec > 0) ? interval_sec : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) static void rk818_bat_set_shtd_vol(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 	u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 	/* set vbat lowest 3.0v shutdown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 	val = rk818_bat_read(di, RK818_VB_MON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 	val &= ~(VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 	val |= (RK818_VBAT_LOW_3V0 | EN_VABT_LOW_SHUT_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) 	rk818_bat_write(di, RK818_VB_MON_REG, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) 	/* disable low irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) 	rk818_bat_set_bits(di, RK818_INT_STS_MSK_REG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 			   VB_LOW_INT_EN, VB_LOW_INT_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) static void rk818_bat_init_fg(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 	rk818_bat_enable_gauge(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 	rk818_bat_init_voltage_kb(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 	rk818_bat_init_coffset(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 	rk818_bat_set_relax_sample(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 	rk818_bat_set_ioffset_sample(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 	rk818_bat_set_ocv_sample(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 	rk818_bat_init_ts1_detect(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 	rk818_bat_init_rsoc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 	rk818_bat_init_coulomb_cap(di, di->nac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 	rk818_bat_init_age_algorithm(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 	rk818_bat_init_chrg_config(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 	rk818_bat_set_shtd_vol(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 	rk818_bat_init_zero_table(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 	rk818_bat_init_caltimer(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 	rk818_bat_init_dsoc_algorithm(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 	di->voltage_avg = rk818_bat_get_avg_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 	di->voltage_ocv = rk818_bat_get_ocv_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 	di->voltage_relax = rk818_bat_get_relax_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 	di->current_avg = rk818_bat_get_avg_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 	di->remain_cap = rk818_bat_get_coulomb_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 	di->dbg_pwr_dsoc = di->dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) 	di->dbg_pwr_rsoc = di->rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 	di->dbg_pwr_vol = di->voltage_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 	rk818_bat_dump_regs(di, 0x99, 0xee);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 	DBG("nac=%d cap=%d ov=%d v=%d rv=%d dl=%d rl=%d c=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 	    di->nac, di->remain_cap, di->voltage_ocv, di->voltage_avg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 	    di->voltage_relax, di->dsoc, di->rsoc, di->current_avg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) static int rk818_bat_parse_dt(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 	u32 out_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 	int length, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 	size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 	struct device_node *np = di->dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 	struct battery_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 	struct device *dev = di->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) 	if (!pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) 	di->pdata = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) 	/* init default param */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) 	pdata->bat_res = DEFAULT_BAT_RES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 	pdata->monitor_sec = DEFAULT_MONITOR_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) 	pdata->pwroff_vol = DEFAULT_PWROFF_VOL_THRESD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 	pdata->sleep_exit_current = DEFAULT_SLP_EXIT_CUR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) 	pdata->sleep_enter_current = DEFAULT_SLP_ENTER_CUR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) 	pdata->bat_mode = MODE_BATTARY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 	pdata->max_soc_offset = DEFAULT_MAX_SOC_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) 	pdata->sample_res = DEFAULT_SAMPLE_RES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) 	pdata->energy_mode = DEFAULT_ENERGY_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) 	pdata->fb_temp = DEFAULT_FB_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) 	pdata->zero_reserve_dsoc = DEFAULT_ZERO_RESERVE_DSOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 	/* parse necessary param */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) 	if (!of_find_property(np, "ocv_table", &length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 		dev_err(dev, "ocv_table not found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) 	pdata->ocv_size = length / sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 	if (pdata->ocv_size <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) 		dev_err(dev, "invalid ocv table\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 	size = sizeof(*pdata->ocv_table) * pdata->ocv_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 	pdata->ocv_table = devm_kzalloc(di->dev, size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 	if (!pdata->ocv_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 	ret = of_property_read_u32_array(np, "ocv_table",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 					 pdata->ocv_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 					 pdata->ocv_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) 	ret = of_property_read_u32(np, "design_capacity", &out_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) 		dev_err(dev, "design_capacity not found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 	pdata->design_capacity = out_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 	ret = of_property_read_u32(np, "design_qmax", &out_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 		dev_err(dev, "design_qmax not found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) 	pdata->design_qmax = out_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) 	ret = of_property_read_u32(np, "max_chrg_voltage", &out_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) 		dev_err(dev, "max_chrg_voltage missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) 	pdata->max_chrg_voltage = out_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 	if (out_value >= 4300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) 		pdata->zero_algorithm_vol = DEFAULT_ALGR_VOL_THRESD2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 		pdata->zero_algorithm_vol = DEFAULT_ALGR_VOL_THRESD1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 	ret = of_property_read_u32(np, "fb_temperature", &pdata->fb_temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 		dev_err(dev, "fb_temperature missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 	ret = of_property_read_u32(np, "sample_res", &pdata->sample_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) 		dev_err(dev, "sample_res missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 	ret = of_property_read_u32(np, "energy_mode", &pdata->energy_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 		dev_err(dev, "energy_mode missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) 	ret = of_property_read_u32(np, "max_soc_offset",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 				   &pdata->max_soc_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) 		dev_err(dev, "max_soc_offset missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 	ret = of_property_read_u32(np, "monitor_sec", &pdata->monitor_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 		dev_err(dev, "monitor_sec missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 	ret = of_property_read_u32(np, "zero_algorithm_vol",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) 				   &pdata->zero_algorithm_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 		dev_err(dev, "zero_algorithm_vol missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 	ret = of_property_read_u32(np, "zero_reserve_dsoc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 				  &pdata->zero_reserve_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) 	ret = of_property_read_u32(np, "virtual_power", &pdata->bat_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) 		dev_err(dev, "virtual_power missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) 	ret = of_property_read_u32(np, "bat_res", &pdata->bat_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) 		dev_err(dev, "bat_res missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) 	ret = of_property_read_u32(np, "sleep_enter_current",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) 				   &pdata->sleep_enter_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) 		dev_err(dev, "sleep_enter_current missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) 	ret = of_property_read_u32(np, "sleep_exit_current",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) 				   &pdata->sleep_exit_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) 		dev_err(dev, "sleep_exit_current missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) 	ret = of_property_read_u32(np, "power_off_thresd", &pdata->pwroff_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) 		dev_err(dev, "power_off_thresd missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) 	if (!of_find_property(np, "ntc_table", &length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) 		pdata->ntc_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 		/* get ntc degree base value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) 		ret = of_property_read_s32(np, "ntc_degree_from_v2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) 					   &pdata->ntc_degree_from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) 			dev_err(dev, "invalid ntc_degree_from_v2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) 		pdata->ntc_size = length / sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) 	if (pdata->ntc_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) 		size = sizeof(*pdata->ntc_table) * pdata->ntc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) 		pdata->ntc_table = devm_kzalloc(di->dev, size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) 		if (!pdata->ntc_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) 		ret = of_property_read_u32_array(np, "ntc_table",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) 						 pdata->ntc_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) 						 pdata->ntc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) 	DBG("the battery dts info dump:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) 	    "bat_res:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 	    "design_capacity:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) 	    "design_qmax :%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 	    "sleep_enter_current:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 	    "sleep_exit_current:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) 	    "zero_algorithm_vol:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 	    "zero_reserve_dsoc:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 	    "monitor_sec:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 	    "max_soc_offset:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 	    "virtual_power:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 	    "pwroff_vol:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 	    "sample_res:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) 	    "ntc_size=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 	    "ntc_degree_from_v2:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) 	    "ntc_degree_to:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 	    pdata->bat_res, pdata->design_capacity, pdata->design_qmax,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) 	    pdata->sleep_enter_current, pdata->sleep_exit_current,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) 	    pdata->zero_algorithm_vol, pdata->zero_reserve_dsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) 	    pdata->monitor_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) 	    pdata->max_soc_offset, pdata->bat_mode, pdata->pwroff_vol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) 	    pdata->sample_res, pdata->ntc_size, pdata->ntc_degree_from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) 	    pdata->ntc_degree_from + pdata->ntc_size - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) 	    );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) static int rk818_bat_parse_dt(struct rk818_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) static const struct of_device_id rk818_battery_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) 	{.compatible = "rk818-battery",},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) static int rk818_battery_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) 	const struct of_device_id *of_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) 			of_match_device(rk818_battery_of_match, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) 	struct rk818_battery *di;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) 	struct rk808 *rk818 = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) 	if (!of_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) 		dev_err(&pdev->dev, "Failed to find matching dt id\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) 	di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) 	if (!di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) 	di->rk818 = rk818;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 	di->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) 	di->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) 	di->regmap = rk818->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) 	platform_set_drvdata(pdev, di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) 	ret = rk818_bat_parse_dt(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) 		dev_err(di->dev, "rk818 battery parse dt failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) 	if (!is_rk818_bat_exist(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) 		di->pdata->bat_mode = MODE_VIRTUAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) 		dev_err(di->dev, "no battery, virtual power mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) 	ret = rk818_bat_init_irqs(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) 	if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) 		dev_err(di->dev, "rk818 bat init irqs failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) 	ret = rk818_bat_init_power_supply(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) 		dev_err(di->dev, "rk818 power supply register failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) 	rk818_bat_init_info(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) 	rk818_bat_init_fg(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) 	rk818_bat_init_sysfs(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) 	rk818_bat_register_fb_notify(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) 	wake_lock_init(&di->wake_lock, WAKE_LOCK_SUSPEND, "rk818_bat_lock");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) 	di->bat_monitor_wq = alloc_ordered_workqueue("%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) 			WQ_MEM_RECLAIM | WQ_FREEZABLE, "rk818-bat-monitor-wq");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 	INIT_DELAYED_WORK(&di->bat_delay_work, rk818_battery_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) 	queue_delayed_work(di->bat_monitor_wq, &di->bat_delay_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) 			   msecs_to_jiffies(TIMER_MS_COUNTS * 5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) 	BAT_INFO("driver version %s\n", DRIVER_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) static int rk818_battery_suspend(struct platform_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) 				 pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) 	struct rk818_battery *di = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) 	u8 val, st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) 	cancel_delayed_work_sync(&di->bat_delay_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) 	di->s2r = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) 	di->sleep_chrg_online = rk818_bat_chrg_online(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) 	di->sleep_chrg_status = rk818_bat_get_chrg_status(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) 	di->current_avg = rk818_bat_get_avg_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) 	di->remain_cap = rk818_bat_get_coulomb_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) 	di->rsoc = rk818_bat_get_rsoc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) 	di->rtc_base = rk818_get_rtc_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) 	rk818_bat_save_data(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) 	st = (rk818_bat_read(di, RK818_SUP_STS_REG) & CHRG_STATUS_MSK) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) 	/* if not CHARGE_FINISH, reinit finish_base.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) 	 * avoid sleep loop between suspend and resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) 	if (di->sleep_chrg_status != CHARGE_FINISH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) 		di->finish_base = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) 	/* avoid: enter suspend from MODE_ZERO: load from heavy to light */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) 	if ((di->work_mode == MODE_ZERO) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) 	    (di->sleep_chrg_online) && (di->current_avg >= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) 		DBG("suspend: MODE_ZERO exit...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) 		/* it need't do prepare for mode finish and smooth, it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) 		 * be done in display_smooth
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) 		if (di->sleep_chrg_status == CHARGE_FINISH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) 			di->work_mode = MODE_FINISH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) 			di->finish_base = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) 			di->work_mode = MODE_SMOOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) 			rk818_bat_smooth_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) 	/* set vbat low than 3.4v to generate a wakeup irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) 	val = rk818_bat_read(di, RK818_VB_MON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) 	val &= (~(VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) 	val |= (RK818_VBAT_LOW_3V4 | EN_VBAT_LOW_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) 	rk818_bat_write(di, RK818_VB_MON_REG, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) 	rk818_bat_set_bits(di, RK818_INT_STS_MSK_REG1, VB_LOW_INT_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) 	BAT_INFO("suspend: dl=%d rl=%d c=%d v=%d cap=%d at=%ld ch=%d st=%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) 		 di->dsoc, di->rsoc, di->current_avg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) 		 rk818_bat_get_avg_voltage(di), rk818_bat_get_coulomb_cap(di),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) 		 di->sleep_dischrg_sec, di->sleep_chrg_online, bat_status[st]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) static int rk818_battery_resume(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) 	struct rk818_battery *di = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) 	int interval_sec, time_step = 0, pwroff_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) 	u8 val, st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) 	di->s2r = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) 	di->current_avg = rk818_bat_get_avg_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) 	di->voltage_relax = rk818_bat_get_relax_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) 	di->voltage_avg = rk818_bat_get_avg_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) 	di->remain_cap = rk818_bat_get_coulomb_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) 	di->rsoc = rk818_bat_get_rsoc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) 	interval_sec = rk818_bat_rtc_sleep_sec(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) 	di->sleep_sum_sec += interval_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) 	pwroff_vol = di->pdata->pwroff_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 	st = (rk818_bat_read(di, RK818_SUP_STS_REG) & CHRG_STATUS_MSK) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) 	if (!di->sleep_chrg_online) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) 		/* only add up discharge sleep seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) 		di->sleep_dischrg_sec += interval_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) 		if (di->voltage_avg <= pwroff_vol + 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) 			time_step = DISCHRG_TIME_STEP1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 			time_step = DISCHRG_TIME_STEP2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) 	BAT_INFO("resume: dl=%d rl=%d c=%d v=%d rv=%d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) 		 "cap=%d dt=%d at=%ld ch=%d st=%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) 		 di->dsoc, di->rsoc, di->current_avg, di->voltage_avg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) 		 di->voltage_relax, rk818_bat_get_coulomb_cap(di), interval_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) 		 di->sleep_dischrg_sec, di->sleep_chrg_online, bat_status[st]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) 	/* sleep: enough time and discharge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) 	if ((di->sleep_dischrg_sec > time_step) && (!di->sleep_chrg_online)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) 		if (rk818_bat_sleep_dischrg(di))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) 			di->sleep_dischrg_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) 	rk818_bat_save_data(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) 	/* set vbat lowest 3.0v shutdown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) 	val = rk818_bat_read(di, RK818_VB_MON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) 	val &= ~(VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) 	val |= (RK818_VBAT_LOW_3V0 | EN_VABT_LOW_SHUT_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) 	rk818_bat_write(di, RK818_VB_MON_REG, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) 	rk818_bat_set_bits(di, RK818_INT_STS_MSK_REG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) 			   VB_LOW_INT_EN, VB_LOW_INT_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) 	/* charge/lowpower lock: for battery work to update dsoc and rsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) 	if ((di->sleep_chrg_online) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) 	    (!di->sleep_chrg_online && di->voltage_avg < di->pdata->pwroff_vol))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) 		wake_lock_timeout(&di->wake_lock, msecs_to_jiffies(2000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) 	queue_delayed_work(di->bat_monitor_wq, &di->bat_delay_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) 			   msecs_to_jiffies(1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) static void rk818_battery_shutdown(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) 	u8 cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) 	struct rk818_battery *di = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) 	cancel_delayed_work_sync(&di->bat_delay_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) 	cancel_delayed_work_sync(&di->calib_delay_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) 	rk818_bat_unregister_fb_notify(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) 	del_timer(&di->caltimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) 	if (base2sec(di->boot_base) < REBOOT_PERIOD_SEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 		cnt = rk818_bat_check_reboot(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 		rk818_bat_save_reboot_cnt(di, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) 	BAT_INFO("shutdown: dl=%d rl=%d c=%d v=%d cap=%d f=%d ch=%d n=%d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) 		 "mode=%d rest=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) 		 di->dsoc, di->rsoc, di->current_avg, di->voltage_avg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) 		 di->remain_cap, di->fcc, rk818_bat_chrg_online(di), cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) 		 di->algo_rest_mode, di->algo_rest_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) static struct platform_driver rk818_battery_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) 	.probe = rk818_battery_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) 	.suspend = rk818_battery_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) 	.resume = rk818_battery_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) 	.shutdown = rk818_battery_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) 		.name = "rk818-battery",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) 		.of_match_table = rk818_battery_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) static int __init battery_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) 	return platform_driver_register(&rk818_battery_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) fs_initcall_sync(battery_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) static void __exit battery_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) 	platform_driver_unregister(&rk818_battery_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) module_exit(battery_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) MODULE_ALIAS("platform:rk818-battery");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) MODULE_AUTHOR("chenjh<chenjh@rock-chips.com>");