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)  * rk816 battery driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Copyright (C) 2017 Rockchip Electronics Co., Ltd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Author: 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/extcon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/fb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/iio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/irq.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 "rk816_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("rk816-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_CHRG_VOL_SEL		CHRG_VOL4200MV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #define DEFAULT_CHRG_CUR_SEL		CHRG_CUR1400MA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #define DEFAULT_CHRG_CUR_INPUT		INPUT_CUR2000MA
^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_MAX_SOC_OFFSET		60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define DEFAULT_FB_TEMP			TEMP_115C
^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 DEFAULT_ZERO_RESERVE_DSOC	10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #define DEFAULT_SAMPLE_RES		20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) /*MODE_VIRTUAL params*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #define VIRTUAL_CURRENT			1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) #define VIRTUAL_VOLTAGE			3888
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #define VIRTUAL_SOC			66
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define VIRTUAL_STATUS			POWER_SUPPLY_STATUS_CHARGING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #define VIRTUAL_PRESET			1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) #define VIRTUAL_AC_ONLINE		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #define VIRTUAL_USB_ONLINE		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #define VIRTUAL_TEMPERATURE		188
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) /* dsoc calib param */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) #define FINISH_CHRG_CUR1		1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) #define FINISH_CHRG_CUR2		1500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) #define FINISH_MAX_SOC_DELAY		20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) #define TERM_CHRG_DSOC			88
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) #define TERM_CHRG_CURR			600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) #define TERM_CHRG_K			650
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) #define SIMULATE_CHRG_INTV		8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) #define SIMULATE_CHRG_CURR		400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) #define SIMULATE_CHRG_K			1500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) #define FULL_CHRG_K			400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) /* zero algorithm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) #define PWROFF_THRESD			3400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) #define MIN_ZERO_DSOC_ACCURACY		10	/*0.01%*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) #define MIN_ZERO_OVERCNT		100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) #define MIN_ACCURACY			1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) #define DEF_PWRPATH_RES			50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) #define	WAIT_DSOC_DROP_SEC		15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) #define	WAIT_SHTD_DROP_SEC		30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) #define MIN_ZERO_GAP_XSOC1		10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) #define MIN_ZERO_GAP_XSOC2		5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) #define MIN_ZERO_GAP_XSOC3		3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) #define MIN_ZERO_GAP_CALIB		5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) #define ADC_CALIB_THRESHOLD		4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) #define ADC_CALIB_LMT_MIN		3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) #define ADC_CALIB_CNT			5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) /* TS detect battery temperature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) #define ADC_CUR_MSK			0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) #define ADC_CUR_20UA			0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) #define ADC_CUR_40UA			0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) #define ADC_CUR_60UA			0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) #define ADC_CUR_80UA			0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) #define NTC_CALC_FACTOR_80UA		80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) #define NTC_CALC_FACTOR_60UA		60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) #define NTC_CALC_FACTOR_40UA		40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) #define NTC_CALC_FACTOR_20UA		20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) #define NTC_80UA_MAX_MEASURE		27500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) #define NTC_60UA_MAX_MEASURE		36666
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) #define NTC_40UA_MAX_MEASURE		55000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) #define NTC_20UA_MAX_MEASURE		110000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) /* time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) #define	POWER_ON_SEC_BASE		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) #define MINUTE(x)				((x) * 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) /* sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) #define SLP_CURR_MAX			40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) #define SLP_CURR_MIN			6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) #define DISCHRG_TIME_STEP1		MINUTE(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) #define DISCHRG_TIME_STEP2		MINUTE(60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) #define SLP_DSOC_VOL_THRESD		3600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) #define REBOOT_PERIOD_SEC		180
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) #define REBOOT_MAX_CNT			80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) #define ZERO_LOAD_LVL1			1400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) #define ZERO_LOAD_LVL2			600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) /* fcc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) #define MIN_FCC				500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) /* DC ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) #define DC_ADC_TRIGGER			150
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) #define TEMP_RECORD_NUM			30
^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 rk816_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			*rk816;
^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;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	struct power_supply		*ac;
^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 workqueue_struct		*usb_charger_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	struct delayed_work		bat_delay_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	struct delayed_work		dc_delay_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	struct delayed_work		calib_delay_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	struct wake_lock		wake_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	struct notifier_block           fb_nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	struct timer_list		caltimer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	time64_t			rtc_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	struct iio_channel		*iio_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	struct notifier_block		cable_cg_nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	struct notifier_block		cable_host_nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	struct notifier_block		cable_discnt_nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	struct delayed_work		usb_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	struct delayed_work		host_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	struct delayed_work		discnt_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	struct extcon_dev		*cable_edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	int				charger_changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	int				bat_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	int				chrg_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	int				res_fac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	int				over_20mR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	bool				is_initialized;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	bool				bat_first_power_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	u8				ac_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	u8				usb_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	u8				otg_in;		/* OTG device attached status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	u8				otg_pmic5v;	/* OTG device power supply from PMIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	u8				dc_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	u8				prop_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	int				cvtlmt_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	int				current_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	int				current_relax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	int				voltage_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	int				voltage_ocv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	int				voltage_relax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	int				voltage_k;/* VCALIB0 VCALIB1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	int				voltage_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	int				remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	int				design_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	int				nac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	int				fcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	int				lock_fcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	int				qmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	int				dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	int				rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	int				poffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	int				fake_offline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	int				age_ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	bool				age_allow_update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	int				age_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	int				age_ocv_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	int				age_voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	int				age_adjust_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	unsigned long			age_keep_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	int				zero_timeout_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	int				zero_remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	int				zero_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	int				zero_linek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	u64				zero_drop_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	u64				shtd_drop_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	int				sm_remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	int				sm_linek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	int				sm_chrg_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	int				sm_dischrg_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	int				algo_rest_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	int				algo_rest_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	int				sleep_sum_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	int				sleep_remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	unsigned long			sleep_dischrg_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	unsigned long			sleep_sum_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	bool				sleep_chrg_online;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	u8				sleep_chrg_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	bool				adc_allow_update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	int                             fb_blank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	bool				s2r; /*suspend to resume*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	u32				work_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	int				temperature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	int				chrg_cur_lp_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	int				chrg_vol_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	int				chrg_cur_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	int				chrg_cur_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	u32				monitor_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	u32				pwroff_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	u32				adc_calib_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	unsigned long			chrg_finish_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	unsigned long			boot_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	unsigned long			flat_match_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	unsigned long			plug_in_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	unsigned long			plug_out_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	u8				halt_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	bool				is_halt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	bool				is_max_soc_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	bool				is_sw_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	bool				is_ocv_calib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	bool				is_first_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	bool				is_force_calib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	int				last_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	u8				cvtlmt_int_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	u8				slp_dcdc_en_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	int				ocv_pre_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	int				ocv_new_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	int				max_pre_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	int				max_new_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	int				force_pre_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	int				force_new_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	int				dbg_cap_low0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	int				dbg_pwr_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	int				dbg_pwr_rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	int				dbg_pwr_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	int				dbg_chrg_min[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	int				dbg_meet_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	int				dbg_calc_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	int				dbg_calc_rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	bool				is_charging;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	unsigned long			charge_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	int				current_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	int				voltage_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) struct led_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	void (*led_init)(struct rk816_battery *di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	void (*led_charging)(struct rk816_battery *di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	void (*led_discharging)(struct rk816_battery *di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	void (*led_charging_full)(struct rk816_battery *di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) static struct led_ops *rk816_led_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) #define DIV(x)	((x) ? (x) : 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) /* 'res_fac' has been *10, so we need divide 10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) #define RES_FAC_MUX(value, res_fac)	((value) * res_fac / 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) /* 'res_fac' has been *10, so we need 'value * 10' before divide 'res_fac' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) #define RES_FAC_DIV(value, res_fac)	((value) * 10 / res_fac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) static u64 get_boot_sec(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	struct timespec64 ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	ktime_get_boottime_ts64(&ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	return ts.tv_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) static unsigned long base2sec(unsigned long x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	if (x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		return (get_boot_sec() > x) ? (get_boot_sec() - x) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) static unsigned long base2min(unsigned long x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	return base2sec(x) / 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) static u32 interpolate(int value, u32 *table, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	u16 d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	for (i = 0; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		if (value < table[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	if ((i > 0) && (i < size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		d = (value - table[i - 1]) * (MAX_INTERPOLATE / (size - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 		d /= table[i] - table[i - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		d = d + (i - 1) * (MAX_INTERPOLATE / (size - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 		d = i * ((MAX_INTERPOLATE + size / 2) / size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	if (d > 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		d = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	return d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) /* (a*b)/c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) static int32_t ab_div_c(u32 a, u32 b, u32 c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	bool sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	u32 ans = MAX_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	int32_t tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	sign = ((((a ^ b) ^ c) & 0x80000000) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	if (c != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		if (sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 			c = -c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		tmp = (a * b + (c >> 1)) / c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 		if (tmp < MAX_INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 			ans = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	if (sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 		ans = -ans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	return ans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) static int rk816_bat_read(struct rk816_battery *di, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	int ret, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	ret = regmap_read(di->regmap, reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 		dev_err(di->dev, "read reg:0x%x failed\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) static int rk816_bat_write(struct rk816_battery *di, u8 reg, u8 buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	ret = regmap_write(di->regmap, reg, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		dev_err(di->dev, "i2c write reg: 0x%2x error\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) static int rk816_bat_set_bits(struct rk816_battery *di, u8 reg, u8 mask, u8 buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	ret = regmap_update_bits(di->regmap, reg, mask, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 		dev_err(di->dev, "write reg:0x%x failed\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) static int rk816_bat_clear_bits(struct rk816_battery *di, u8 reg, u8 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	ret = regmap_update_bits(di->regmap, reg, mask, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		dev_err(di->dev, "clr reg:0x%02x failed\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	return ret;
^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 void rk816_bat_dump_regs(struct rk816_battery *di, u8 start, u8 end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	if (!dbg_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	DBG("dump regs from: 0x%x-->0x%x\n", start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	for (i = start; i < end; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		DBG("0x%x: 0x%0x\n", i, rk816_bat_read(di, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) static bool rk816_bat_chrg_online(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	return (di->usb_in || di->ac_in || di->dc_in) ? true : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) static int rk816_bat_get_coulomb_cap(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	int cap, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	val |= rk816_bat_read(di, RK816_GASCNT_REG3) << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	val |= rk816_bat_read(di, RK816_GASCNT_REG2) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	val |= rk816_bat_read(di, RK816_GASCNT_REG1) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	val |= rk816_bat_read(di, RK816_GASCNT_REG0) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	if (!di->over_20mR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		cap = RES_FAC_MUX(val / 2390, di->res_fac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 		cap = RES_FAC_DIV(val / 2390, di->res_fac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	return cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) static int rk816_bat_get_rsoc(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	int remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	remain_cap = rk816_bat_get_coulomb_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	return (remain_cap + di->fcc / 200) * 100 / DIV(di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) static ssize_t bat_info_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 			      const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	char cmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	struct rk816_battery *di = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	ret = sscanf(buf, "%c", &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	if (ret != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		dev_err(di->dev, "error! cmd require only one args\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	if (cmd == 'n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		rk816_bat_set_bits(di, RK816_MISC_MARK_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 				   FG_RESET_NOW, FG_RESET_NOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	else if (cmd == 'm')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 		rk816_bat_set_bits(di, RK816_MISC_MARK_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 				   FG_RESET_LATE, FG_RESET_LATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	else if (cmd == 'c')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 		rk816_bat_clear_bits(di, RK816_MISC_MARK_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 				     FG_RESET_LATE | FG_RESET_NOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	else if (cmd == 'r')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 		BAT_INFO("0x%2x\n", rk816_bat_read(di, RK816_MISC_MARK_REG));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 		BAT_INFO("command error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) static struct device_attribute rk816_bat_attr[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	__ATTR(bat, 0664, NULL, bat_info_store),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) static void rk816_bat_enable_input_current(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	buf = rk816_bat_read(di, RK816_BAT_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	buf |= USB_SYS_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	rk816_bat_write(di, RK816_BAT_CTRL_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) static void rk816_bat_disable_input_current(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	buf = rk816_bat_read(di, RK816_BAT_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	buf &= ~USB_SYS_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	rk816_bat_write(di, RK816_BAT_CTRL_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) static int rk816_bat_is_input_enabled(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	buf = rk816_bat_read(di, RK816_BAT_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	return !!(buf & USB_SYS_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) static void rk816_bat_enable_gauge(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	buf = rk816_bat_read(di, RK816_TS_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	buf |= GG_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	rk816_bat_write(di, RK816_TS_CTRL_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) static void rk816_bat_save_age_level(struct rk816_battery *di, u8 level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	rk816_bat_write(di, RK816_UPDATE_LEVE_REG, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) static u8 rk816_bat_get_age_level(struct  rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	return rk816_bat_read(di, RK816_UPDATE_LEVE_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) static int rk816_bat_get_vcalib0(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	val |= rk816_bat_read(di, RK816_VCALIB0_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	val |= rk816_bat_read(di, RK816_VCALIB0_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	DBG("<%s>. voffset0: 0x%x\n", __func__, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	return val;
^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 rk816_bat_get_vcalib1(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	val |= rk816_bat_read(di, RK816_VCALIB1_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	val |= rk816_bat_read(di, RK816_VCALIB1_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	DBG("<%s>. voffset1: 0x%x\n", __func__, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) static int rk816_bat_get_ioffset(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	val |= rk816_bat_read(di, RK816_IOFFSET_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	val |= rk816_bat_read(di, RK816_IOFFSET_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	DBG("<%s>. ioffset: 0x%x\n", __func__, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) static int rk816_bat_get_coffset(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	val |= rk816_bat_read(di, RK816_CAL_OFFSET_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	val |= rk816_bat_read(di, RK816_CAL_OFFSET_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	DBG("<%s>. coffset: 0x%x\n", __func__, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) static void rk816_bat_set_coffset(struct rk816_battery *di, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	buf = (val >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	rk816_bat_write(di, RK816_CAL_OFFSET_REGH, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	buf = (val >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	rk816_bat_write(di, RK816_CAL_OFFSET_REGL, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	DBG("<%s>. coffset: 0x%x\n", __func__, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) static void rk816_bat_init_voltage_kb(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	int vcalib0, vcalib1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	vcalib0 = rk816_bat_get_vcalib0(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	vcalib1 = rk816_bat_get_vcalib1(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	di->voltage_k = (4200 - 3000) * 1000 / DIV(vcalib1 - vcalib0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	di->voltage_b = 4200 - (di->voltage_k * vcalib1) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	DBG("voltage_k=%d(*1000),voltage_b=%d\n", di->voltage_k, di->voltage_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) static int rk816_bat_get_ocv_voltage(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	int vol, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	val |= rk816_bat_read(di, RK816_BAT_OCV_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	val |= rk816_bat_read(di, RK816_BAT_OCV_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	vol = di->voltage_k * val / 1000 + di->voltage_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	return (vol * 1100 / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) static int rk816_bat_get_avg_voltage(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	int vol, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	val |= rk816_bat_read(di, RK816_BAT_VOL_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	val |= rk816_bat_read(di, RK816_BAT_VOL_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	vol = di->voltage_k * val / 1000 + di->voltage_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	return (vol * 1100 / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) static int rk816_bat_get_usb_voltage(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	int vol, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	val |= rk816_bat_read(di, RK816_USB_ADC_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	val |= rk816_bat_read(di, RK816_USB_ADC_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	vol = di->voltage_k * val / 1000 + di->voltage_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	return (vol * 1400 / 1100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) static bool is_rk816_bat_relax_mode(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	status = rk816_bat_read(di, RK816_GGSTS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	if (!(status & RELAX_VOL1_UPD) || !(status & RELAX_VOL2_UPD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) static u16 rk816_bat_get_relax_vol1(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	u16 vol, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	val |= rk816_bat_read(di, RK816_RELAX_VOL1_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	val |= rk816_bat_read(di, RK816_RELAX_VOL1_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	vol = di->voltage_k * val / 1000 + di->voltage_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	return (vol * 1100 / 1000);
^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 u16 rk816_bat_get_relax_vol2(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	u16 vol, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	val |= rk816_bat_read(di, RK816_RELAX_VOL2_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	val |= rk816_bat_read(di, RK816_RELAX_VOL2_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	vol = di->voltage_k * val / 1000 + di->voltage_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	return (vol * 1100 / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) static u16 rk816_bat_get_relax_voltage(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	u16 relax_vol1, relax_vol2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	if (!is_rk816_bat_relax_mode(di))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	relax_vol1 = rk816_bat_get_relax_vol1(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	relax_vol2 = rk816_bat_get_relax_vol2(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	return relax_vol1 > relax_vol2 ? relax_vol1 : relax_vol2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) static int rk816_bat_get_avg_current(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	int cur, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	val |= rk816_bat_read(di, RK816_BAT_CUR_AVG_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	val |= rk816_bat_read(di, RK816_BAT_CUR_AVG_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	if (val & 0x800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		val -= 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	if (!di->over_20mR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		cur = RES_FAC_MUX(val * 1506, di->res_fac) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		cur = RES_FAC_DIV(val * 1506, di->res_fac) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	return cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) static int rk816_bat_get_relax_cur1(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	val |= rk816_bat_read(di, RK816_RELAX_CUR1_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	val |= rk816_bat_read(di, RK816_RELAX_CUR1_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	if (val & 0x800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 		val -= 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	return (val * 1506 / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) static int rk816_bat_get_relax_cur2(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	val |= rk816_bat_read(di, RK816_RELAX_CUR2_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	val |= rk816_bat_read(di, RK816_RELAX_CUR2_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	if (val & 0x800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 		val -= 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	return (val * 1506 / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) static int rk816_bat_get_relax_current(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	int relax_cur1, relax_cur2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	if (!is_rk816_bat_relax_mode(di))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	relax_cur1 = rk816_bat_get_relax_cur1(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	relax_cur2 = rk816_bat_get_relax_cur2(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	return (relax_cur1 < relax_cur2) ? relax_cur1 : relax_cur2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) static int rk816_bat_vol_to_ocvsoc(struct rk816_battery *di, int voltage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	u32 *ocv_table, temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	int ocv_size, ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	ocv_table = di->pdata->ocv_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	ocv_size = di->pdata->ocv_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	temp = interpolate(voltage, ocv_table, ocv_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	ocv_soc = ab_div_c(temp, MAX_PERCENTAGE, MAX_INTERPOLATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	return ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) static int rk816_bat_vol_to_ocvcap(struct rk816_battery *di, int voltage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	u32 *ocv_table, temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	int ocv_size, cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	ocv_table = di->pdata->ocv_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	ocv_size = di->pdata->ocv_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	temp = interpolate(voltage, ocv_table, ocv_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	cap = ab_div_c(temp, di->fcc, MAX_INTERPOLATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	return cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) static int rk816_bat_vol_to_zerosoc(struct rk816_battery *di, int voltage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	u32 *ocv_table, temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	int ocv_size, ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	ocv_table = di->pdata->zero_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	ocv_size = di->pdata->ocv_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	temp = interpolate(voltage, ocv_table, ocv_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	ocv_soc = ab_div_c(temp, MAX_PERCENTAGE, MAX_INTERPOLATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	return ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) static int rk816_bat_vol_to_zerocap(struct rk816_battery *di, int voltage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	u32 *ocv_table, temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	int ocv_size, cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	ocv_table = di->pdata->zero_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	ocv_size = di->pdata->ocv_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	temp = interpolate(voltage, ocv_table, ocv_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	cap = ab_div_c(temp, di->fcc, MAX_INTERPOLATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	return cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) static int rk816_bat_get_iadc(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	val |= rk816_bat_read(di, RK816_BAT_CUR_AVG_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	val |= rk816_bat_read(di, RK816_BAT_CUR_AVG_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	if (val > 2047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		val -= 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) static bool is_rk816_bat_st_cvtlim(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	return (rk816_bat_read(di, RK816_INT_STS_REG1) & 0x80) ? true : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) static bool rk816_bat_adc_calib(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	int i, ioffset, coffset, adc, save_coffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	if ((di->chrg_status != CHARGE_FINISH) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	    (di->adc_calib_cnt > ADC_CALIB_CNT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	    (base2min(di->boot_base) < ADC_CALIB_LMT_MIN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	    (abs(di->current_avg) < ADC_CALIB_THRESHOLD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	    (is_rk816_bat_st_cvtlim(di)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	di->adc_calib_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	save_coffset = rk816_bat_get_coffset(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	for (i = 0; i < 5; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		if (!rk816_bat_chrg_online(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 			rk816_bat_set_coffset(di, save_coffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 			BAT_INFO("quit, charger plugout when calib adc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 			return false;
^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) 		/* check status and int cvtlmt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 		if (is_rk816_bat_st_cvtlim(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 			rk816_bat_set_coffset(di, save_coffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 			BAT_INFO("1 cvtlmt(st) when calib adc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 		enable_irq(di->cvtlmt_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 		msleep(2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		disable_irq(di->cvtlmt_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		if (di->cvtlmt_int_event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 			di->cvtlmt_int_event = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 			rk816_bat_set_coffset(di, save_coffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 			BAT_INFO("1 cvtlmt(int) when calib adc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 		/* it's ok to update coffset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 		adc = rk816_bat_get_iadc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 		coffset = rk816_bat_get_coffset(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		rk816_bat_set_coffset(di, coffset + adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		/* check status and int cvtlmt again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		if (is_rk816_bat_st_cvtlim(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 			rk816_bat_set_coffset(di, save_coffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 			BAT_INFO("2 cvtlmt(st) when calib adc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		enable_irq(di->cvtlmt_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		msleep(2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		disable_irq(di->cvtlmt_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 		if (di->cvtlmt_int_event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 			di->cvtlmt_int_event = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 			rk816_bat_set_coffset(di, save_coffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 			BAT_INFO("2 cvtlmt(int) when calib adc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		/* it's ok to check calib adc result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		adc = rk816_bat_get_iadc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		if (abs(adc) < ADC_CALIB_THRESHOLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 			coffset = rk816_bat_get_coffset(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 			ioffset = rk816_bat_get_ioffset(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 			di->poffset = coffset - ioffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 			rk816_bat_write(di, RK816_PCB_IOFFSET_REG, di->poffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 			BAT_INFO("new offset:c=0x%x, i=0x%x, p=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 				 coffset, ioffset, di->poffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 			BAT_INFO("coffset calib again %d.., max_cnt=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 				 i, di->adc_calib_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 			rk816_bat_set_coffset(di, coffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	rk816_bat_set_coffset(di, save_coffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) static void rk816_bat_set_ioffset_sample(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	u8 ggcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	ggcon = rk816_bat_read(di, RK816_GGCON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	ggcon &= ~ADC_CAL_MIN_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	ggcon |= ADC_CAL_8MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	rk816_bat_write(di, RK816_GGCON_REG, ggcon);
^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 void rk816_bat_set_ocv_sample(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	u8 ggcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	ggcon = rk816_bat_read(di, RK816_GGCON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	ggcon &= ~OCV_SAMP_MIN_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	ggcon |= OCV_SAMP_8MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	rk816_bat_write(di, RK816_GGCON_REG, ggcon);
^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) static void rk816_bat_restart_relax(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	u8 ggsts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	ggsts = rk816_bat_read(di, RK816_GGSTS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	ggsts &= ~RELAX_VOL12_UPD_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	rk816_bat_write(di, RK816_GGSTS_REG, ggsts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) static void rk816_bat_set_relax_sample(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	int enter_thres, exit_thres, filter_thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	struct battery_platform_data *pdata = di->pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	filter_thres = pdata->sleep_filter_current * 1000 / 1506;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	if (!di->over_20mR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		enter_thres = RES_FAC_DIV(pdata->sleep_enter_current * 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 					  di->res_fac) / 1506;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		exit_thres = RES_FAC_DIV(pdata->sleep_exit_current * 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 					 di->res_fac) / 1506;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		enter_thres = RES_FAC_MUX(pdata->sleep_enter_current * 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 					  di->res_fac) / 1506;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		exit_thres = RES_FAC_MUX(pdata->sleep_exit_current * 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 					 di->res_fac) / 1506;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	/* set relax enter and exit threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	buf = enter_thres & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	rk816_bat_write(di, RK816_RELAX_ENTRY_THRES_REGL, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	buf = (enter_thres >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	rk816_bat_write(di, RK816_RELAX_ENTRY_THRES_REGH, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	buf = exit_thres & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	rk816_bat_write(di, RK816_RELAX_EXIT_THRES_REGL, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	buf = (exit_thres >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	rk816_bat_write(di, RK816_RELAX_EXIT_THRES_REGH, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	/* set sample current threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	buf = filter_thres & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	rk816_bat_write(di, RK816_SLEEP_CON_SAMP_CUR_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	/* reset relax update state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	rk816_bat_restart_relax(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	DBG("<%s>. sleep_enter_current = %d, sleep_exit_current = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	    __func__, pdata->sleep_enter_current, pdata->sleep_exit_current);
^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) /* high load: current < 0 with charger in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956)  * System will not shutdown while dsoc=0% with charging state(ac_in),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957)  * which will cause over discharge, so oppose status before report states.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) static void rk816_bat_lowpwr_check(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	static u64 time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	int pwr_off_thresd = di->pdata->pwroff_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	if (di->current_avg < 0 && di->voltage_avg < pwr_off_thresd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		if (!time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 			time = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		if ((base2sec(time) > MINUTE(1)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 		    (di->voltage_avg <= pwr_off_thresd - 50)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 			di->fake_offline = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 			if (di->voltage_avg <= pwr_off_thresd - 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 				di->dsoc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 			BAT_INFO("low power, soc=%d, current=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 				 di->dsoc, di->current_avg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 		time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		di->fake_offline = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	DBG("<%s>. t=%lu, dsoc=%d, current=%d, fake_offline=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	    __func__, base2sec(time), di->dsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	    di->current_avg, di->fake_offline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) static bool is_rk816_bat_exist(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	return (rk816_bat_read(di, RK816_SUP_STS_REG) & BAT_EXS) ? true : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) static bool is_rk816_bat_first_pwron(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	buf = rk816_bat_read(di, RK816_GGSTS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	if (buf & BAT_CON) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		buf &= ~BAT_CON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 		rk816_bat_write(di, RK816_GGSTS_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) static u8 rk816_bat_get_pwroff_min(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	u8 now_min, last_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	now_min = rk816_bat_read(di, RK816_NON_ACT_TIMER_CNT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	last_min = rk816_bat_read(di, RK816_NON_ACT_TIMER_CNT_REG_SAVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	rk816_bat_write(di, RK816_NON_ACT_TIMER_CNT_REG_SAVE, now_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	return (now_min != last_min) ? now_min : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) static u8 is_rk816_bat_initialized(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	u8 val = rk816_bat_read(di, RK816_MISC_MARK_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	if (val & FG_INIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		val &= ~FG_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		rk816_bat_write(di, RK816_MISC_MARK_REG, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static bool is_rk816_bat_ocv_valid(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	return (!di->is_initialized && di->pwroff_min >= 30) ? true : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) static void rk816_bat_init_age_algorithm(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	int age_level, ocv_soc, ocv_cap, ocv_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	if (di->bat_first_power_on || is_rk816_bat_ocv_valid(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		DBG("<%s> enter.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		ocv_vol = rk816_bat_get_ocv_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		ocv_soc = rk816_bat_vol_to_ocvsoc(di, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		ocv_cap = rk816_bat_vol_to_ocvcap(di, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 		if (ocv_soc < 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 			di->age_voltage = ocv_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 			di->age_ocv_cap = ocv_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 			di->age_ocv_soc = ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 			di->age_adjust_cap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 			if (ocv_soc <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 				di->age_level = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 			else if (ocv_soc < 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 				di->age_level = 95;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 			else if (ocv_soc < 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 				di->age_level = 90;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 				di->age_level = 80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 			age_level = rk816_bat_get_age_level(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 			if (age_level > di->age_level) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 				di->age_allow_update = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 				age_level -= 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 				if (age_level <= 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 					age_level = 80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 				rk816_bat_save_age_level(di, age_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 				di->age_allow_update = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 				di->age_keep_sec = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 			BAT_INFO("init_age_algorithm: age_vol:%d, age_ocv_cap:%d, age_ocv_soc:%d, old_age_level:%d, age_allow_update:%d, new_age_level:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 				 di->age_voltage, di->age_ocv_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 				 ocv_soc, age_level, di->age_allow_update,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 				 di->age_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		}
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) static enum power_supply_property rk816_bat_props[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	POWER_SUPPLY_PROP_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	POWER_SUPPLY_PROP_CURRENT_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	POWER_SUPPLY_PROP_PRESENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	POWER_SUPPLY_PROP_HEALTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	POWER_SUPPLY_PROP_CAPACITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	POWER_SUPPLY_PROP_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	POWER_SUPPLY_PROP_CHARGE_COUNTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	POWER_SUPPLY_PROP_CHARGE_FULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) static int rk816_bat_ac_set_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 				     enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 				     const union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	struct rk816_battery *di = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 		if (val->intval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 			rk816_bat_enable_input_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 			rk816_bat_disable_input_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	return 0;
^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 rk816_bat_usb_set_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 				      enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 				      const union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	struct rk816_battery *di = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 		if (val->intval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 			rk816_bat_enable_input_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 			rk816_bat_disable_input_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) static int rk816_get_capacity_leve(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	if (di->pdata->bat_mode == MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 		return POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	if (di->dsoc < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 		return POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	else if (di->dsoc <= 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 		return POWER_SUPPLY_CAPACITY_LEVEL_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	else if (di->dsoc <= 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 		return POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	else if (di->dsoc <= 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		return POWER_SUPPLY_CAPACITY_LEVEL_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 		return POWER_SUPPLY_CAPACITY_LEVEL_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) static int rk816_battery_time_to_full(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	int time_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	int cap_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	if (di->pdata->bat_mode == MODE_VIRTUAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 		time_sec = 3600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	} else if (di->voltage_avg > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		cap_temp = di->pdata->design_capacity - di->remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 		if (cap_temp < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 			cap_temp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 		time_sec = (3600 * cap_temp) / di->voltage_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 		time_sec = 3600 * 24; /* One day */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	return time_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) static int rk816_battery_get_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 				      enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 				      union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	struct rk816_battery *di = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	case POWER_SUPPLY_PROP_CURRENT_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 		val->intval = di->current_avg * 1000;/*uA*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 		if (di->pdata->bat_mode == MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 			val->intval = VIRTUAL_CURRENT * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		val->intval = di->voltage_avg * 1000;/*uV*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 		if (di->pdata->bat_mode == MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 			val->intval = VIRTUAL_VOLTAGE * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	case POWER_SUPPLY_PROP_PRESENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 		val->intval = is_rk816_bat_exist(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 		if (di->pdata->bat_mode == MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 			val->intval = VIRTUAL_PRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	case POWER_SUPPLY_PROP_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 		val->intval = di->dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		if (di->pdata->bat_mode == MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 			val->intval = VIRTUAL_SOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		DBG("<%s>. report dsoc: %d\n", __func__, val->intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 		val->intval = rk816_get_capacity_leve(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	case POWER_SUPPLY_PROP_HEALTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 		val->intval = POWER_SUPPLY_HEALTH_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	case POWER_SUPPLY_PROP_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 		val->intval = di->prop_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 		if (di->pdata->bat_mode == MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 			val->intval = VIRTUAL_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		if (!rk816_bat_is_input_enabled(di))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	case POWER_SUPPLY_PROP_TEMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		val->intval = di->temperature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 		if (di->pdata->bat_mode == MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 			val->intval = VIRTUAL_TEMPERATURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	case POWER_SUPPLY_PROP_CHARGE_COUNTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 		val->intval = di->charge_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	case POWER_SUPPLY_PROP_CHARGE_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 		val->intval = di->pdata->design_capacity * 1000;/* uAh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 		val->intval = rk816_battery_time_to_full(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) static enum power_supply_property rk816_ac_props[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	POWER_SUPPLY_PROP_ONLINE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	POWER_SUPPLY_PROP_VOLTAGE_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	POWER_SUPPLY_PROP_CURRENT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) static enum power_supply_property rk816_usb_props[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	POWER_SUPPLY_PROP_ONLINE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	POWER_SUPPLY_PROP_VOLTAGE_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	POWER_SUPPLY_PROP_CURRENT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) static int rk816_bat_ac_get_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 				     enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 				     union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	struct rk816_battery *di = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	case POWER_SUPPLY_PROP_ONLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 		if (di->pdata->bat_mode == MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 			val->intval = VIRTUAL_AC_ONLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 		else if (di->fake_offline)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 			val->intval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 			val->intval = di->ac_in | di->dc_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 		val->intval = di->voltage_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	case POWER_SUPPLY_PROP_CURRENT_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 		val->intval = di->current_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 		val->intval = rk816_bat_is_input_enabled(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) static int rk816_bat_usb_get_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 				      enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 				      union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	struct rk816_battery *di = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	case POWER_SUPPLY_PROP_ONLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 		if (di->pdata->bat_mode == MODE_VIRTUAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 			val->intval = VIRTUAL_USB_ONLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 		else if (di->fake_offline)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 			val->intval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 			val->intval = di->usb_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 		val->intval = di->voltage_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	case POWER_SUPPLY_PROP_CURRENT_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 		val->intval = di->current_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 		val->intval = rk816_bat_is_input_enabled(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) static int rk816_bat_writable_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 				       enum power_supply_property psp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) static const struct power_supply_desc rk816_bat_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	.name		= "battery",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	.type		= POWER_SUPPLY_TYPE_BATTERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	.properties	= rk816_bat_props,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	.num_properties	= ARRAY_SIZE(rk816_bat_props),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	.get_property	= rk816_battery_get_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) static const struct power_supply_desc rk816_ac_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	.name = "ac",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	.type = POWER_SUPPLY_TYPE_MAINS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	.properties = rk816_ac_props,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	.num_properties = ARRAY_SIZE(rk816_ac_props),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	.get_property = rk816_bat_ac_get_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	.set_property = rk816_bat_ac_set_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	.property_is_writeable = rk816_bat_writable_property,
^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 const struct power_supply_desc rk816_usb_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	.name = "usb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	.type = POWER_SUPPLY_TYPE_USB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	.properties = rk816_usb_props,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	.num_properties = ARRAY_SIZE(rk816_usb_props),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	.get_property = rk816_bat_usb_get_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	.set_property = rk816_bat_usb_set_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	.property_is_writeable = rk816_bat_writable_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) static int rk816_bat_init_power_supply(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	struct power_supply_config psy_cfg = { .drv_data = di, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	di->bat = devm_power_supply_register(di->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 					     &rk816_bat_desc, &psy_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	if (IS_ERR(di->bat)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 		dev_err(di->dev, "register bat power supply fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 		return PTR_ERR(di->bat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	di->ac = devm_power_supply_register(di->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 					    &rk816_ac_desc, &psy_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	if (IS_ERR(di->ac)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 		dev_err(di->dev, "register ac power supply fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 		return PTR_ERR(di->ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	di->usb = devm_power_supply_register(di->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 					     &rk816_usb_desc, &psy_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	if (IS_ERR(di->usb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 		dev_err(di->dev, "register usb power supply fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 		return PTR_ERR(di->usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) static void rk816_bat_save_cap(struct rk816_battery *di, int capacity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	static u32 old_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	if (capacity >= di->qmax)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 		capacity = di->qmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	if (capacity <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 		capacity = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	if (old_cap == capacity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	old_cap = capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	buf = (capacity >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	rk816_bat_write(di, RK816_REMAIN_CAP_REG3, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	buf = (capacity >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	rk816_bat_write(di, RK816_REMAIN_CAP_REG2, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	buf = (capacity >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	rk816_bat_write(di, RK816_REMAIN_CAP_REG1, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	buf = (capacity >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	rk816_bat_write(di, RK816_REMAIN_CAP_REG0, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) static int rk816_bat_get_prev_cap(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	val |= rk816_bat_read(di, RK816_REMAIN_CAP_REG3) << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	val |= rk816_bat_read(di, RK816_REMAIN_CAP_REG2) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	val |= rk816_bat_read(di, RK816_REMAIN_CAP_REG1) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	val |= rk816_bat_read(di, RK816_REMAIN_CAP_REG0) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) static void rk816_bat_save_fcc(struct rk816_battery *di, u32 fcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	buf = (fcc >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	rk816_bat_write(di, RK816_NEW_FCC_REG3, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	buf = (fcc >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	rk816_bat_write(di, RK816_NEW_FCC_REG2, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	buf = (fcc >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	rk816_bat_write(di, RK816_NEW_FCC_REG1, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	buf = (fcc >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	rk816_bat_write(di, RK816_NEW_FCC_REG0, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	BAT_INFO("save fcc: %d\n", fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) static int rk816_bat_get_fcc(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	u32 fcc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	fcc |= rk816_bat_read(di, RK816_NEW_FCC_REG3) << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	fcc |= rk816_bat_read(di, RK816_NEW_FCC_REG2) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	fcc |= rk816_bat_read(di, RK816_NEW_FCC_REG1) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	fcc |= rk816_bat_read(di, RK816_NEW_FCC_REG0) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	if (fcc < MIN_FCC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 		BAT_INFO("invalid fcc(%d), use design cap", fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 		fcc = di->pdata->design_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 		rk816_bat_save_fcc(di, fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	} else if (fcc > di->pdata->design_qmax) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 		BAT_INFO("invalid fcc(%d), use qmax", fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 		fcc = di->pdata->design_qmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 		rk816_bat_save_fcc(di, fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	return fcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) static int rk816_bat_get_lock_fcc(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	int fcc, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	/* check lock flag, 1: yes, 0: no */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	reg = rk816_bat_read(di, RK816_GGSTS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 	if ((reg & FCC_LOCK) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	val |= rk816_bat_read(di, RK816_FCC_GASCNT_REG3) << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 	val |= rk816_bat_read(di, RK816_FCC_GASCNT_REG2) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	val |= rk816_bat_read(di, RK816_FCC_GASCNT_REG1) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 	val |= rk816_bat_read(di, RK816_FCC_GASCNT_REG0) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	fcc = val / 2390;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 	/* clear lock flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 	reg &= ~FCC_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 	rk816_bat_write(di, RK816_GGSTS_REG, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	BAT_INFO("lock fcc = %d\n", fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 	return fcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) static void rk816_bat_save_dsoc(struct rk816_battery *di, u8 save_soc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	static int last_soc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 	if (last_soc != save_soc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 		rk816_bat_write(di, RK816_SOC_REG, save_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 		last_soc = save_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) static int rk816_bat_get_prev_dsoc(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	return rk816_bat_read(di, RK816_SOC_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) static void rk816_bat_save_reboot_cnt(struct rk816_battery *di, u8 save_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	rk816_bat_write(di, RK816_REBOOT_CNT_REG, save_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) static void rk816_bat_init_leds(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	if (rk816_led_ops && rk816_led_ops->led_init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 		rk816_led_ops->led_init(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 		BAT_INFO("leds initialized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) static void rk816_bat_update_leds(struct rk816_battery *di, int prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	static int old_prop = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	if (prop == old_prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 	old_prop = prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 	switch (prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 	case POWER_SUPPLY_STATUS_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 		if (rk816_led_ops && rk816_led_ops->led_charging_full) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 			rk816_led_ops->led_charging_full(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 			BAT_INFO("charging full led on\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	case POWER_SUPPLY_STATUS_CHARGING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 		if (rk816_led_ops && rk816_led_ops->led_charging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 			rk816_led_ops->led_charging(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 			BAT_INFO("charging led on\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 	case POWER_SUPPLY_STATUS_DISCHARGING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 		if (rk816_led_ops && rk816_led_ops->led_discharging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 			rk816_led_ops->led_discharging(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 			BAT_INFO("discharging led on\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 		BAT_INFO("Unknown led update\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	}
^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 rk816_bat_set_chrg_current(struct rk816_battery *di,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 				       u8 chrg_current)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	u8 chrg_ctrl_reg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	chrg_ctrl_reg1 = rk816_bat_read(di, RK816_CHRG_CTRL_REG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 	chrg_ctrl_reg1 &= ~CHRG_CUR_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 	chrg_ctrl_reg1 |= (chrg_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	rk816_bat_write(di, RK816_CHRG_CTRL_REG1, chrg_ctrl_reg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) static void rk816_bat_set_input_current(struct rk816_battery *di,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 					int input_current)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	u8 usb_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	if (di->pdata->bat_mode == MODE_VIRTUAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 		BAT_INFO("virtual power test mode, set max input current\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 		input_current = di->chrg_cur_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	usb_ctrl = rk816_bat_read(di, RK816_USB_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	usb_ctrl &= ~INPUT_CUR_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 	usb_ctrl |= (input_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	rk816_bat_write(di, RK816_USB_CTRL_REG, usb_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) static void rk816_bat_set_chrg_param(struct rk816_battery *di,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 				     enum charger_t charger_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	u8 buf, usb_ctrl, chrg_ctrl1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	const char *charger_name[] = {"NONE", "NONE USB", "USB", "AC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 				      "CDP1.5A", "DC", "NONE DC"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 	switch (charger_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	case USB_TYPE_UNKNOWN_CHARGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 		di->usb_in = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 		di->ac_in = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 		di->dc_in = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 		di->prop_status = POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 		rk816_bat_set_chrg_current(di, di->chrg_cur_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 		rk816_bat_set_input_current(di, INPUT_CUR450MA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 		power_supply_changed(di->bat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 		power_supply_changed(di->usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 		power_supply_changed(di->ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	case USB_TYPE_NONE_CHARGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 		di->usb_in = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 		di->ac_in = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 		if (di->dc_in == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 			di->prop_status = POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 			rk816_bat_set_chrg_current(di, di->chrg_cur_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 			rk816_bat_set_input_current(di, INPUT_CUR450MA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 		power_supply_changed(di->usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 		power_supply_changed(di->ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	case USB_TYPE_USB_CHARGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 		di->usb_in = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 		di->ac_in = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 		di->prop_status = POWER_SUPPLY_STATUS_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 		if (di->dc_in == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 			rk816_bat_set_chrg_current(di, di->chrg_cur_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 			rk816_bat_set_input_current(di, INPUT_CUR450MA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 		power_supply_changed(di->usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	case USB_TYPE_CDP_CHARGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 		di->usb_in = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 		di->ac_in = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 		di->prop_status = POWER_SUPPLY_STATUS_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 		if (di->dc_in == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 			rk816_bat_set_chrg_current(di, di->chrg_cur_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 			rk816_bat_set_input_current(di, INPUT_CUR1500MA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 		power_supply_changed(di->usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 	case USB_TYPE_AC_CHARGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 		di->ac_in = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 		di->usb_in = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 		di->prop_status = POWER_SUPPLY_STATUS_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 		rk816_bat_set_chrg_current(di, di->chrg_cur_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 		rk816_bat_set_input_current(di, di->chrg_cur_input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 		power_supply_changed(di->ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 	case DC_TYPE_DC_CHARGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 		di->dc_in = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 		di->prop_status = POWER_SUPPLY_STATUS_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 		rk816_bat_set_chrg_current(di, di->chrg_cur_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 		rk816_bat_set_input_current(di, di->chrg_cur_input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 		power_supply_changed(di->ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	case DC_TYPE_NONE_CHARGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 		di->dc_in = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 		 * check by pmic int avoid usb error notify:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 		 * when plug in dc, usb may error notify usb/ac plug in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 		 * while dc plug out, the "ac/usb_in" still hold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 		buf = rk816_bat_read(di, RK816_VB_MON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 		if ((buf & PLUG_IN_STS) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 			di->ac_in = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 			di->usb_in = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 			di->prop_status = POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 			rk816_bat_set_chrg_current(di, di->chrg_cur_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 			rk816_bat_set_input_current(di, INPUT_CUR450MA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 		} else if (di->usb_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 			rk816_bat_set_chrg_current(di, di->chrg_cur_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 			rk816_bat_set_input_current(di, INPUT_CUR450MA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 			di->prop_status = POWER_SUPPLY_STATUS_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 		power_supply_changed(di->usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 		power_supply_changed(di->ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 		di->prop_status = POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 	di->charger_changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 	usb_ctrl = rk816_bat_read(di, RK816_USB_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 	chrg_ctrl1 = rk816_bat_read(di, RK816_CHRG_CTRL_REG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	BAT_INFO("set charger type: %s, current: input=%d, chrg=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 		 charger_name[charger_type],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 		 CHRG_CUR_INPUT[usb_ctrl & 0x0f],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 		 CHRG_CUR_SEL[chrg_ctrl1 & 0x0f]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	if (di->dsoc == 100 && rk816_bat_chrg_online(di))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 		di->prop_status = POWER_SUPPLY_STATUS_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	rk816_bat_update_leds(di, di->prop_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) static void rk816_bat_set_otg_in(struct rk816_battery *di, int online)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 	di->otg_in = online;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679)  * -----: VBUS-5V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)  * #####: PMIC_INT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)  *		A	140ms	   D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)  *		|------------------>>>>>>>>>>>>>>>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)  *		|	B   C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)  * ##########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)  *		|	    #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)  *		|   100ms   #   F    E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)  * --------------	    ##############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)  * [PMIC]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692)  *	A: charger plugin event(vbus-5v on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)  *	C: pmic reaction time finish, [A~C] = 100ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)  *	D: pmic switch to charging mode, start charging, [A~D] = 140ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)  * [Software]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697)  *	B: PLUG_IN_STS=0, we think it's not charging mode, so enable otg+boost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698)  *	   but actually, PLUG_IN_STS is not effective now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)  *	F: pmic reaction finish, PLUG_IN_STS is effective and we do check again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)  *	E: output-5v mode really works(enable boost+otg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)  * [Mistake detail]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)  *	1. Charger plugin at spot-A and switch to charing mode at spot-D.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)  *	2. Software check PLUG_IN_STS=0 at spot-B, so we think it's not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)  *	   charging mode and we enable boost+otg, and this really works at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)  *	   spot-E(because delay of i2c transfer or other).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)  *	3. It's a pity that pmic has been changed to charing mode at spot-D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)  *	   earlier than spot-E.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)  * After above mistake, we enable otg+boost in charing mode. Then, boost will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)  * burn off if we plugout charger.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)  * [Solution]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)  *	we should abey the rule: Don't enable boost while in charging mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)  * We should enable otg first at spot-B, trying to switch to output-5v mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716)  * then delay 140ms(pmic reaction and other) to check effective PLUG_IN_STS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)  * again at spot-F, if PLUG_IN_STS=1, means it's charging mode now, we abandont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)  * enable boost and disable otg. Otherwise, we can turn on boost safely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) static void rk816_bat_set_otg_power(struct rk816_battery *di, int power)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	switch (power) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	case USB_OTG_POWER_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 		if (di->otg_pmic5v) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 			BAT_INFO("otg5v is on yet, ignore..\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 		/* (spot-B). for safe, detect vbus-5v by pmic self */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 		buf = rk816_bat_read(di, RK816_VB_MON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 		if (buf & PLUG_IN_STS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 			BAT_INFO("detect vbus-5v suppling, deny otg on..\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 		/* (spot-B). enable otg, try to switch to output-5v mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 		rk816_bat_set_bits(di, RK816_DCDC_EN_REG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 				   BOOST_OTG_MASK, BOOST_OFF_OTG_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 		 * pmic need about 140ms to switch to charging mode, so wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 		 * 140ms and check charger again. if still check vbus-5v online,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 		 * that means it's charger mode now, we should turn off boost
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		 * and otg, then return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 		msleep(140);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 		/* spot-F */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 		buf = rk816_bat_read(di, RK816_VB_MON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 		if (buf & PLUG_IN_STS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 			rk816_bat_set_bits(di, RK816_DCDC_EN_REG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 					   BOOST_OTG_MASK, BOOST_OTG_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 			BAT_INFO("detect vbus-5v suppling too, deny otg on\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 			break;
^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) 		 * reach here, means pmic switch to output-5v mode ok, it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 		 * safe to enable boost-5v on output mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 		rk816_bat_set_bits(di, RK816_DCDC_EN_REG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 				   BOOST_OTG_MASK, BOOST_OTG_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 		di->otg_pmic5v = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 	case USB_OTG_POWER_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 		if (!di->otg_pmic5v) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 			BAT_INFO("otg5v is off yet, ignore..\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 			rk816_bat_set_bits(di, RK816_DCDC_EN_REG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 					   BOOST_OTG_MASK, BOOST_OTG_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 			di->otg_pmic5v = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) static enum charger_t rk816_bat_get_adc_dc_state(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 	if (!di->iio_chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 		di->iio_chan = iio_channel_get(&di->rk816->i2c->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 		if (IS_ERR(di->iio_chan)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 			di->iio_chan = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 			return DC_TYPE_NONE_CHARGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 	if (iio_read_channel_raw(di->iio_chan, &val) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 		pr_err("read channel error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 		return DC_TYPE_NONE_CHARGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 	return (val >= DC_ADC_TRIGGER) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 		DC_TYPE_DC_CHARGER : DC_TYPE_NONE_CHARGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) static enum charger_t rk816_bat_get_gpio_dc_state(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 	int level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 	if (!gpio_is_valid(di->pdata->dc_det_pin))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 		return DC_TYPE_NONE_CHARGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 	level = gpio_get_value(di->pdata->dc_det_pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	return (level == di->pdata->dc_det_level) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 		DC_TYPE_DC_CHARGER : DC_TYPE_NONE_CHARGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) static enum charger_t rk816_bat_get_dc_state(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 	enum charger_t type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	if (di->pdata->dc_det_adc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 		type = rk816_bat_get_adc_dc_state(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 		type = rk816_bat_get_gpio_dc_state(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) static void rk816_bat_dc_delay_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 	enum charger_t type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 	static enum charger_t old_type = USB_TYPE_UNKNOWN_CHARGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 	struct rk816_battery *di = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 				struct rk816_battery, dc_delay_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 	type = rk816_bat_get_dc_state(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 	if (old_type == type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 	old_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 	if (type == DC_TYPE_DC_CHARGER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 		BAT_INFO("detect dc charger in..\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 		rk816_bat_set_chrg_param(di, DC_TYPE_DC_CHARGER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 		/* check otg supply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 		if (di->otg_in && di->pdata->power_dc2otg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 			BAT_INFO("otg power from dc adapter\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 			rk816_bat_set_otg_power(di, USB_OTG_POWER_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 		BAT_INFO("detect dc charger out..\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 		rk816_bat_set_chrg_param(di, DC_TYPE_NONE_CHARGER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 		/* check otg supply, power on anyway */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 		if (di->otg_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 			BAT_INFO("charge disable, enable otg\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 			 * must wait 200ms to wait 5v-input fade away before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 			 * enable boost
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 			msleep(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 			rk816_bat_set_otg_power(di, USB_OTG_POWER_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 	/* adc need check all the time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 	if (di->pdata->dc_det_adc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 		queue_delayed_work(di->usb_charger_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 				   &di->dc_delay_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 				   msecs_to_jiffies(1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) static int rk816_bat_fb_notifier(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 				 unsigned long event, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 	struct rk816_battery *di;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 	struct fb_event *evdata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 	if (event != FB_EVENT_BLANK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 		return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 	di = container_of(nb, struct rk816_battery, fb_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 	di->fb_blank = *(int *)evdata->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 	return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) static int rk816_bat_register_fb_notify(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 	memset(&di->fb_nb, 0, sizeof(di->fb_nb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 	di->fb_nb.notifier_call = rk816_bat_fb_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 	return fb_register_client(&di->fb_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) static int rk816_bat_unregister_fb_notify(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 	return fb_unregister_client(&di->fb_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) static void rk816_bat_init_coulomb_cap(struct rk816_battery *di, u32 capacity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	u32 cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 	if (!di->over_20mR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 		cap = RES_FAC_DIV(capacity * 2390, di->res_fac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 		cap = RES_FAC_MUX(capacity * 2390, di->res_fac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 	buf = (cap >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 	rk816_bat_write(di, RK816_GASCNT_CAL_REG3, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 	buf = (cap >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 	rk816_bat_write(di, RK816_GASCNT_CAL_REG2, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	buf = (cap >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	rk816_bat_write(di, RK816_GASCNT_CAL_REG1, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 	buf = (cap >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 	rk816_bat_write(di, RK816_GASCNT_CAL_REG0, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 	di->remain_cap = capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 	di->rsoc = rk816_bat_get_rsoc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) static u8 rk816_bat_get_halt_cnt(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 	return rk816_bat_read(di, RK816_HALT_CNT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) static void rk816_bat_inc_halt_cnt(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 	u8 cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 	cnt = rk816_bat_read(di, RK816_HALT_CNT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 	rk816_bat_write(di, RK816_HALT_CNT_REG, ++cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) static bool is_rk816_bat_last_halt(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 	int pre_cap = rk816_bat_get_prev_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 	int now_cap = rk816_bat_get_coulomb_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 	/* over 10%: system halt last time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 	if (abs(now_cap - pre_cap) > (di->fcc / 10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 		rk816_bat_inc_halt_cnt(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) static void rk816_bat_first_pwron(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 	int ocv_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 	rk816_bat_save_fcc(di, di->design_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 	ocv_vol = rk816_bat_get_ocv_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 	di->fcc = rk816_bat_get_fcc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 	di->nac = rk816_bat_vol_to_ocvcap(di, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 	di->rsoc = rk816_bat_vol_to_ocvsoc(di, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 	di->dsoc = di->rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 	di->is_first_on = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 	BAT_INFO("first on: dsoc=%d, rsoc=%d cap=%d, fcc=%d, ov=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 		 di->dsoc, di->rsoc, di->nac, di->fcc, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) static void rk816_bat_not_first_pwron(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 	int now_cap, pre_soc, pre_cap, ocv_cap, ocv_soc, ocv_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 	di->fcc = rk816_bat_get_fcc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 	pre_soc = rk816_bat_get_prev_dsoc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 	pre_cap = rk816_bat_get_prev_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 	now_cap = rk816_bat_get_coulomb_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 	di->is_halt = is_rk816_bat_last_halt(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 	di->halt_cnt = rk816_bat_get_halt_cnt(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 	di->is_initialized = is_rk816_bat_initialized(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 	di->is_ocv_calib = is_rk816_bat_ocv_valid(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 	if (di->is_initialized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 		BAT_INFO("initialized yet..\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 		goto finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 	} else if (di->is_halt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 		BAT_INFO("system halt last time... cap: pre=%d, now=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 			 pre_cap, now_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 		if (now_cap < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 			now_cap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 		rk816_bat_init_coulomb_cap(di, now_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 		pre_cap = now_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 		pre_soc = di->rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 		goto finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 	} else if (di->is_ocv_calib) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 		ocv_vol = rk816_bat_get_ocv_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 		ocv_soc = rk816_bat_vol_to_ocvsoc(di, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 		ocv_cap = rk816_bat_vol_to_ocvcap(di, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 		pre_cap = ocv_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 		di->ocv_pre_dsoc = pre_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 		di->ocv_new_dsoc = ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 		if (abs(ocv_soc - pre_soc) >= di->pdata->max_soc_offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 			di->ocv_pre_dsoc = pre_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 			di->ocv_new_dsoc = ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 			di->is_max_soc_offset = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 			BAT_INFO("trigger max soc offset, dsoc: %d -> %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 				 pre_soc, ocv_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 			pre_soc = ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 		BAT_INFO("OCV calib: cap=%d, rsoc=%d\n", ocv_cap, ocv_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 	} else if (di->pwroff_min > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 		ocv_vol = rk816_bat_get_ocv_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 		ocv_soc = rk816_bat_vol_to_ocvsoc(di, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 		ocv_cap = rk816_bat_vol_to_ocvcap(di, ocv_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 		di->force_pre_dsoc = pre_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 		di->force_new_dsoc = ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 		if (abs(ocv_soc - pre_soc) >= 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 			di->is_force_calib = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 			BAT_INFO("dsoc force calib: %d -> %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 				 pre_soc, ocv_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 			pre_soc = ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 			pre_cap = ocv_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 	di->dsoc = pre_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 	di->nac = pre_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 	if (di->nac < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 		di->nac = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 	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 2027) 		 di->dsoc, di->nac, rk816_bat_get_avg_voltage(di),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 		 rk816_bat_get_ocv_voltage(di), rk816_bat_get_relax_voltage(di),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 		 di->pwroff_min, rk816_bat_get_prev_dsoc(di),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 		 rk816_bat_get_prev_cap(di));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) static bool rk816_bat_ocv_sw_reset(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 	buf = rk816_bat_read(di, RK816_MISC_MARK_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 	if (((buf & FG_RESET_LATE) && di->pwroff_min >= 30) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 	    (buf & FG_RESET_NOW)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 		buf &= ~FG_RESET_LATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 		buf &= ~FG_RESET_NOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 		rk816_bat_write(di, RK816_MISC_MARK_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 		BAT_INFO("manual reset fuel gauge\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) static void rk816_bat_setup_ocv_table(struct rk816_battery *di, int temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 	int i, idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 	int temp_h, temp_l, percent, volt_htemp, volt_ltemp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 	int *temp_t = di->pdata->temp_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 	int temp_t_num = di->pdata->temp_t_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	if (temp_t_num < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 	DBG("<%s>. temperature=%d\n", __func__, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 	/* Out of MIN, select MIN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 	if (temp < temp_t[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 		DBG("<%s>. Out MIN\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 		di->pdata->ocv_table = di->pdata->table_t[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 		return;
^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) 	/* Out of MAX, select MAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 	if (temp > temp_t[temp_t_num - 1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 		DBG("<%s>. Out MAX\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 		di->pdata->ocv_table = di->pdata->table_t[temp_t_num - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 	/* Exactly match some one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 	for (i = 0; i < temp_t_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 		if (temp == temp_t[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 			DBG("<%s>. Match: %d'C\n", __func__, temp_t[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 			di->pdata->ocv_table = di->pdata->table_t[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 			return;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 	/* Find position of current temperature, must be fond */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	for (i = 0; i < temp_t_num - 1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 		if ((temp > temp_t[i]) && (temp < temp_t[i + 1])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 			idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 	DBG("<%s>. found! idx = %d\n", __func__, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 	/* calculate percent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 	temp_l = temp_t[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 	temp_h = temp_t[idx + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 	percent = (temp - temp_l) * 100 / DIV(temp_h - temp_l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 	/* Fill in new ocv table members */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 	for (i = 0; i < di->pdata->ocv_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 		volt_ltemp = di->pdata->table_t[idx][i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 		volt_htemp = di->pdata->table_t[idx + 1][i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 		di->pdata->ocv_table[i] = volt_ltemp +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 			(volt_htemp - volt_ltemp) * percent / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 		DBG("#low=%d'C[%dmv], me=%d'C[%dmv], high=%d'C[%dmv]. percent=%d, delta=%dmv\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 		    temp_l, volt_ltemp, temp, di->pdata->ocv_table[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 		    temp_h, volt_htemp, percent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 		    (volt_htemp - volt_ltemp) * percent / 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) static void rk816_bat_init_rsoc(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 	di->bat_first_power_on = is_rk816_bat_first_pwron(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 	di->is_sw_reset = rk816_bat_ocv_sw_reset(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 	di->pwroff_min = rk816_bat_get_pwroff_min(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 	if (di->bat_first_power_on || di->is_sw_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 		rk816_bat_first_pwron(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 		rk816_bat_not_first_pwron(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) static u8 rk816_bat_get_chrg_status(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 	u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 	status = rk816_bat_read(di, RK816_SUP_STS_REG) & CHRG_STATUS_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 	switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 	case CHARGE_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 		DBG("CHARGE-OFF ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 	case DEAD_CHARGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 		BAT_INFO("DEAD CHARGE...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 	case TRICKLE_CHARGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 		BAT_INFO("TRICKLE CHARGE...\n ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 	case CC_OR_CV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 		DBG("CC or CV...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 	case CHARGE_FINISH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 		DBG("CHARGE FINISH...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 	case USB_OVER_VOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 		BAT_INFO("USB OVER VOL...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 	case BAT_TMP_ERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 		BAT_INFO("BAT TMP ERROR...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 	case TIMER_ERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 		BAT_INFO("TIMER ERROR...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 	case USB_EXIST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 		BAT_INFO("USB EXIST...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 	case USB_EFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 		BAT_INFO("USB EFF...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 		BAT_INFO("UNKNOWN STATUS...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 	return status;
^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) static u8 rk816_bat_fb_temp(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 	int index, fb_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 	reg = DEFAULT_FB_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 	fb_temp = di->pdata->fb_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 	for (index = 0; index < ARRAY_SIZE(FEED_BACK_TEMP); index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 		if (fb_temp < FEED_BACK_TEMP[index])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 		reg = (index << FB_TEMP_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 	return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) static void rk816_bat_select_sample_res(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 	if (di->pdata->sample_res == 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 		di->over_20mR = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 		di->res_fac = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 	} else if (di->pdata->sample_res > 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 		di->over_20mR = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 		di->res_fac = di->pdata->sample_res * 10 / 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 		di->over_20mR = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 		di->res_fac = 20 * 10 / di->pdata->sample_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) static u8 rk816_bat_decode_input_current(struct rk816_battery *di,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 					u32 input_current)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 	u8 val = DEFAULT_CHRG_CUR_INPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 	u8 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 	for (index = 2; index < ARRAY_SIZE(CHRG_CUR_INPUT); index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 		if (input_current < 850 && input_current > 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 			val = 0x0;/* 450mA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 		} else if (input_current <= 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 			val = 0x1;/* 80mA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 			if (input_current < CHRG_CUR_INPUT[index])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 			val = (index << CHRG_CRU_INPUT_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) static u8 rk816_bat_decode_chrg_current(struct rk816_battery *di,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 				       u32 chrg_current)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 	u8 val = DEFAULT_CHRG_CUR_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 	u8 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 	if (di->pdata->sample_res < 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 		if (chrg_current > 2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 			chrg_current = RES_FAC_DIV(chrg_current, di->res_fac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 			chrg_current = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	} else if (di->pdata->sample_res > 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 		chrg_current = RES_FAC_MUX(chrg_current, di->res_fac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 		if (chrg_current > 2400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 			chrg_current = 2400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 		if (chrg_current < 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 			chrg_current = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 	for (index = 0; index < ARRAY_SIZE(CHRG_CUR_SEL); index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 		if (chrg_current < CHRG_CUR_SEL[index])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 		val = (index << CHRG_CRU_SEL_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) static u8 rk816_bat_decode_chrg_vol(struct rk816_battery *di,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 				    u32 chrg_vol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 	u8 val = DEFAULT_CHRG_VOL_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	u8 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 	for (index = 0; index < ARRAY_SIZE(CHRG_VOL_SEL); index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 		if (chrg_vol < CHRG_VOL_SEL[index])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 		val = (index << CHRG_VOL_SEL_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) static void rk816_bat_select_chrg_cv(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 	di->chrg_vol_sel = rk816_bat_decode_chrg_vol(di,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 					di->pdata->max_chrg_voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 	di->chrg_cur_input = rk816_bat_decode_input_current(di,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 					di->pdata->max_input_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 	di->chrg_cur_sel = rk816_bat_decode_chrg_current(di,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 					di->pdata->max_chrg_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 	DBG("<%s>. vol = 0x%x, input = 0x%x, sel = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 	    __func__, di->chrg_vol_sel, di->chrg_cur_input, di->chrg_cur_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) static u8 rk816_bat_finish_ma(struct rk816_battery *di, int fcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 	u8 ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 	if (fcc > 5000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 		ma = FINISH_250MA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	else if (fcc >= 4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 		ma = FINISH_200MA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 	else if (fcc >= 3000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 		ma = FINISH_150MA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 		ma = FINISH_100MA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 	/* adjust ma according to sample resistor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 	if (di->pdata->sample_res < 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 		/* ma should div 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 		if (ma == FINISH_200MA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 			ma = FINISH_100MA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 		else if (ma == FINISH_250MA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 			ma = FINISH_150MA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 	} else if (di->pdata->sample_res > 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 		/* ma should mux 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 		if (ma == FINISH_100MA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 			ma = FINISH_200MA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 		else if (ma == FINISH_150MA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 			ma = FINISH_250MA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 	return ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) static void rk816_bat_init_chrg_config(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 	u8 chrg_ctrl1, usb_ctrl, chrg_ctrl2, chrg_ctrl3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 	u8 sup_sts, thermal, ggcon, finish_ma, fb_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 	rk816_bat_select_chrg_cv(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 	finish_ma = rk816_bat_finish_ma(di, di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 	fb_temp = rk816_bat_fb_temp(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 	ggcon = rk816_bat_read(di, RK816_GGCON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 	sup_sts = rk816_bat_read(di, RK816_SUP_STS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 	thermal = rk816_bat_read(di, RK816_THERMAL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 	usb_ctrl = rk816_bat_read(di, RK816_USB_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 	chrg_ctrl1 = rk816_bat_read(di, RK816_CHRG_CTRL_REG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 	chrg_ctrl2 = rk816_bat_read(di, RK816_CHRG_CTRL_REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 	chrg_ctrl3 = rk816_bat_read(di, RK816_CHRG_CTRL_REG3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 	/* set charge current and voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 	usb_ctrl &= ~INPUT_CUR_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 	usb_ctrl |= di->chrg_cur_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 	chrg_ctrl1 = (CHRG_EN) | (di->chrg_vol_sel | di->chrg_cur_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 	/* set charge finish current */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 	chrg_ctrl3 |= CHRG_TERM_DIG_SIGNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 	chrg_ctrl2 &= ~FINISH_CUR_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 	chrg_ctrl2 |= finish_ma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 	/* disable cccv mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 	chrg_ctrl3 &= ~CHRG_TIMER_CCCV_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 	/* enable voltage limit and enable input current limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 	sup_sts |= USB_VLIMIT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 	sup_sts |= USB_CLIMIT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 	/* set feed back temperature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 	if (di->pdata->fb_temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 		usb_ctrl |= CHRG_CT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 		usb_ctrl &= ~CHRG_CT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 	thermal &= ~FB_TEMP_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 	thermal |= fb_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 	/* adc current mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 	ggcon |= ADC_CUR_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 	ggcon |= AVG_CUR_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 	rk816_bat_write(di, RK816_GGCON_REG, ggcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 	rk816_bat_write(di, RK816_SUP_STS_REG, sup_sts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 	rk816_bat_write(di, RK816_THERMAL_REG, thermal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 	rk816_bat_write(di, RK816_USB_CTRL_REG, usb_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 	rk816_bat_write(di, RK816_CHRG_CTRL_REG1, chrg_ctrl1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 	rk816_bat_write(di, RK816_CHRG_CTRL_REG2, chrg_ctrl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 	rk816_bat_write(di, RK816_CHRG_CTRL_REG3, chrg_ctrl3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) static void rk816_bat_init_poffset(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 	int coffset, ioffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 	coffset = rk816_bat_get_coffset(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 	ioffset = rk816_bat_get_ioffset(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 	di->poffset = coffset - ioffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) static void rk816_bat_caltimer_isr(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 	struct rk816_battery *di = from_timer(di, t, caltimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 	mod_timer(&di->caltimer, jiffies + MINUTE(8) * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 	queue_delayed_work(di->bat_monitor_wq, &di->calib_delay_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 			   msecs_to_jiffies(10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) static void rk816_bat_internal_calib(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 	int ioffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 	struct rk816_battery *di = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 			struct rk816_battery, calib_delay_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 	ioffset = rk816_bat_get_ioffset(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 	rk816_bat_set_coffset(di, di->poffset + ioffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 	rk816_bat_init_voltage_kb(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 	BAT_INFO("caltimer: ioffset=0x%x, coffset=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 		 ioffset, rk816_bat_get_coffset(di));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) static void rk816_bat_init_caltimer(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 	timer_setup(&di->caltimer, rk816_bat_caltimer_isr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 	di->caltimer.expires = jiffies + MINUTE(8) * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 	add_timer(&di->caltimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 	INIT_DELAYED_WORK(&di->calib_delay_work, rk816_bat_internal_calib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) static void rk816_bat_init_zero_table(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 	int i, diff, min, max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 	size_t ocv_size, length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 	ocv_size = di->pdata->ocv_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 	length = sizeof(di->pdata->zero_table) * ocv_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 	di->pdata->zero_table =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 			devm_kzalloc(di->dev, length, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 	if (!di->pdata->zero_table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 		di->pdata->zero_table = di->pdata->ocv_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 		dev_err(di->dev, "malloc zero table fail\n");
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 	min = di->pdata->pwroff_vol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 	max = di->pdata->ocv_table[ocv_size - 4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 	diff = (max - min) / DIV(ocv_size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 	for (i = 0; i < ocv_size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 		di->pdata->zero_table[i] = min + (i * diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 	if (!dbg_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 	for (i = 0; i < ocv_size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 		DBG("zero[%d] = %d\n", i, di->pdata->zero_table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 	for (i = 0; i < ocv_size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 		DBG("ocv[%d] = %d\n", i, di->pdata->ocv_table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) static void rk816_bat_calc_sm_linek(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 	int linek, current_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 	u8 diff, delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 	delta = abs(di->dsoc - di->rsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 	diff = delta * 3;/* speed:3/4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 	current_avg = rk816_bat_get_avg_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 	if (current_avg >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 		if (di->dsoc < di->rsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 			linek = 1000 * (delta + diff) / DIV(diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 		else if (di->dsoc > di->rsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 			linek = 1000 * diff / DIV(delta + diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 			linek = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 		di->dbg_meet_soc = (di->dsoc >= di->rsoc) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 				   (di->dsoc + diff) : (di->rsoc + diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 		if (di->dsoc < di->rsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 			linek = -1000 * diff / DIV(delta + diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 		else if (di->dsoc > di->rsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 			linek = -1000 * (delta + diff) / DIV(diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 			linek = -1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 		di->dbg_meet_soc = (di->dsoc >= di->rsoc) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 				   (di->dsoc - diff) : (di->rsoc - diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 	di->sm_linek = linek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 	di->sm_remain_cap = di->remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 	di->dbg_calc_dsoc = di->dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 	di->dbg_calc_rsoc = di->rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 	DBG("<%s>.diff=%d, k=%d, cur=%d\n", __func__, diff, linek, current_avg);
^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) static void rk816_bat_calc_zero_linek(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 	int dead_voltage, ocv_voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 	int voltage_avg, current_avg, vsys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 	int ocv_cap, dead_cap, xsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 	int ocv_soc, dead_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 	int pwroff_vol, org_linek = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 	int min_gap_xsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 	if ((abs(di->current_avg) < 400) && (di->dsoc > 5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 		pwroff_vol = di->pdata->pwroff_vol + 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 		pwroff_vol = di->pdata->pwroff_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 	/* calc estimate ocv voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 	voltage_avg = rk816_bat_get_avg_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 	current_avg = rk816_bat_get_avg_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 	vsys = voltage_avg + (current_avg * DEF_PWRPATH_RES) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 	DBG("ZERO0: shtd_vol: org = %d, now = %d, zero_reserve_dsoc = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 	    di->pdata->pwroff_vol, pwroff_vol, di->pdata->zero_reserve_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	dead_voltage = pwroff_vol - current_avg *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 				(di->bat_res + DEF_PWRPATH_RES) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 	ocv_voltage = voltage_avg - (current_avg * di->bat_res) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 	DBG("ZERO0: dead_voltage(shtd) = %d, ocv_voltage(now) = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 	    dead_voltage, ocv_voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 	/* calc estimate soc and cap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 	dead_soc = rk816_bat_vol_to_zerosoc(di, dead_voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 	dead_cap = rk816_bat_vol_to_zerocap(di, dead_voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 	DBG("ZERO0: dead_soc = %d, dead_cap = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 	    dead_soc, dead_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 	ocv_soc = rk816_bat_vol_to_zerosoc(di, ocv_voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 	ocv_cap = rk816_bat_vol_to_zerocap(di, ocv_voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 	DBG("ZERO0: ocv_soc = %d, ocv_cap = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 	    ocv_soc, ocv_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 	/* xsoc: available rsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 	xsoc = ocv_soc - dead_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 	/* min_gap_xsoc: reserve xsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 	if (abs(current_avg) > ZERO_LOAD_LVL1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 		min_gap_xsoc = MIN_ZERO_GAP_XSOC3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 	else if (abs(current_avg) > ZERO_LOAD_LVL2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 		min_gap_xsoc = MIN_ZERO_GAP_XSOC2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 		min_gap_xsoc = MIN_ZERO_GAP_XSOC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 	if ((xsoc <= 30) && (di->dsoc >= di->pdata->zero_reserve_dsoc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 		min_gap_xsoc = min_gap_xsoc + MIN_ZERO_GAP_CALIB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 	di->zero_remain_cap = di->remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 	di->zero_timeout_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 	if ((di->dsoc <= 1) && (xsoc > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 		di->zero_linek = 400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 		di->zero_drop_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 	} else if (xsoc >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 		di->zero_drop_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 		di->zero_linek = (di->zero_dsoc + xsoc / 2) / DIV(xsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 		org_linek = di->zero_linek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 		/* battery energy mode to use up voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 		if ((di->pdata->energy_mode) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 		    (xsoc - di->dsoc >= MIN_ZERO_GAP_XSOC3) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 		    (di->dsoc <= 10) && (di->zero_linek < 300)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 			di->zero_linek = 300;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 			DBG("ZERO-new: zero_linek adjust step0...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 		/* reserve enough power yet, slow down any way */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 		} else if ((xsoc - di->dsoc >= min_gap_xsoc) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 			   ((xsoc - di->dsoc >= MIN_ZERO_GAP_XSOC2) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 			    (di->dsoc <= 10) && (xsoc > 15))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 			if (xsoc <= 20 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 			    di->dsoc >= di->pdata->zero_reserve_dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 				di->zero_linek = 1200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 			else if (xsoc - di->dsoc >= 2 * min_gap_xsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 				di->zero_linek = 400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 			else if (xsoc - di->dsoc >= 3 + min_gap_xsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 				di->zero_linek = 600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 				di->zero_linek = 800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 			DBG("ZERO-new: zero_linek adjust step1...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 		/* control zero mode beginning enter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 		} else if ((di->zero_linek > 1800) && (di->dsoc > 70)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 			di->zero_linek = 1800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 			DBG("ZERO-new: zero_linek adjust step2...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 		/* dsoc close to xsoc: it must reserve power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 		} else if ((di->zero_linek > 1000) && (di->zero_linek < 1200)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 			di->zero_linek = 1200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 			DBG("ZERO-new: zero_linek adjust step3...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 		/* dsoc[5~15], dsoc < xsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 		} else if ((di->dsoc <= 15 && di->dsoc > 5) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 			   (di->zero_linek <= 1200)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 			/* slow down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 			if ((xsoc - di->dsoc) >= min_gap_xsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 				di->zero_linek = 800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 			/* reserve power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 				di->zero_linek = 1200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 			DBG("ZERO-new: zero_linek adjust step4...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 		/* dsoc[5, 100], dsoc < xsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 		} else if ((di->zero_linek < 1000) && (di->dsoc >= 5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 			if ((xsoc - di->dsoc) < min_gap_xsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 				/* reserve power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 				di->zero_linek = 1200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 				if (abs(di->current_avg) > 500)/* heavy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 					di->zero_linek = 900;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 					di->zero_linek = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 			DBG("ZERO-new: zero_linek adjust step5...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 		/* dsoc[0~5], dsoc < xsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 		} else if ((di->zero_linek < 1000) && (di->dsoc <= 5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 			if ((xsoc - di->dsoc) <= 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 				di->zero_linek = 1200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 				di->zero_linek = 800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 			DBG("ZERO-new: zero_linek adjust step6...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 		/* xsoc < 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 		di->zero_linek = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 		if (!di->zero_drop_sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 			di->zero_drop_sec = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 		if (base2sec(di->zero_drop_sec) >= WAIT_DSOC_DROP_SEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 			DBG("ZERO0: t=%lu\n", base2sec(di->zero_drop_sec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 			di->zero_drop_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 			di->dsoc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 			di->zero_dsoc = (di->dsoc + 1) * 1000 -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 						MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 	if (voltage_avg < pwroff_vol - 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 		if (!di->shtd_drop_sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 			di->shtd_drop_sec = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 		if (base2sec(di->shtd_drop_sec) > WAIT_SHTD_DROP_SEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 			BAT_INFO("voltage extreme low...soc:%d->0\n", di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 			di->shtd_drop_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 			di->dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 		di->shtd_drop_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 	DBG("ZERO-new: org_linek=%d, zero_linek=%d, dsoc=%d, Xsoc=%d, rsoc=%d, gap=%d, v=%d, vsys=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 	    "ZERO-new: di->zero_dsoc=%d, zero_remain_cap=%d, zero_drop=%ld, sht_drop=%ld\n\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 	    org_linek, di->zero_linek, di->dsoc, xsoc, di->rsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 	    min_gap_xsoc, voltage_avg, vsys, di->zero_dsoc, di->zero_remain_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 	    base2sec(di->zero_drop_sec), base2sec(di->shtd_drop_sec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) static void rk816_bat_finish_algo_prepare(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 	di->chrg_finish_base = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 	if (!di->chrg_finish_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 		di->chrg_finish_base = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) static void rk816_bat_smooth_algo_prepare(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 	int tmp_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 	tmp_soc = di->sm_chrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 	if (tmp_soc != di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 		di->sm_chrg_dsoc = di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 	tmp_soc = di->sm_dischrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 	if (tmp_soc != di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 		di->sm_dischrg_dsoc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 		(di->dsoc + 1) * 1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 	DBG("<%s>. tmp_soc=%d, dsoc=%d, dsoc:sm_dischrg=%d, sm_chrg=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 	    __func__, tmp_soc, di->dsoc, di->sm_dischrg_dsoc, di->sm_chrg_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 	rk816_bat_calc_sm_linek(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) static void rk816_bat_zero_algo_prepare(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 	int tmp_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 	di->zero_timeout_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 	tmp_dsoc = di->zero_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 	if (tmp_dsoc != di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 		di->zero_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 	DBG("<%s>. first calc, reinit linek\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 	rk816_bat_calc_zero_linek(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) static void rk816_bat_calc_zero_algorithm(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 	int tmp_soc = 0, sm_delta_dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 	tmp_soc = di->zero_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 	if (tmp_soc == di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 	DBG("<%s>. enter: dsoc=%d, rsoc=%d\n", __func__, di->dsoc, di->rsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 	/* when discharge slow down, take sm chrg into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 	if (di->dsoc < di->rsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 		/* take sm charge rest into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 		tmp_soc = di->sm_chrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 		if (tmp_soc == di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 			sm_delta_dsoc = di->sm_chrg_dsoc - di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 			di->sm_chrg_dsoc = di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 			di->zero_dsoc += sm_delta_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 			DBG("ZERO1: take sm chrg,delta=%d\n", sm_delta_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 	/* when discharge speed up, take sm dischrg into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 	if (di->dsoc > di->rsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 		/* take sm discharge rest into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 		tmp_soc = di->sm_dischrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 		if (tmp_soc == di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 			sm_delta_dsoc = di->sm_dischrg_dsoc -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 				((di->dsoc + 1) * 1000 - MIN_ACCURACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 			di->sm_dischrg_dsoc = (di->dsoc + 1) * 1000 -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 								MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 			di->zero_dsoc += sm_delta_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 			DBG("ZERO1: take sm dischrg,delta=%d\n", sm_delta_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 	/* check overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 	if (di->zero_dsoc > (di->dsoc + 1) * 1000 - MIN_ACCURACY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 		DBG("ZERO1: zero dsoc overflow: %d\n", di->zero_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 		di->zero_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 	/* check new dsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 	tmp_soc = di->zero_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 	if (tmp_soc != di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 		/* avoid dsoc jump when heavy load */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 		if ((di->dsoc - tmp_soc) > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 			di->dsoc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 			di->zero_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 			DBG("ZERO1: heavy load...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 			di->dsoc = tmp_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 		di->zero_drop_sec = 0;
^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) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 	DBG("ZERO1: zero_dsoc(Y0)=%d, dsoc=%d, rsoc=%d, tmp_soc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 	    di->zero_dsoc, di->dsoc, di->rsoc, tmp_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 	DBG("ZERO1: sm_dischrg_dsoc=%d, sm_chrg_dsoc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 	    di->sm_dischrg_dsoc, di->sm_chrg_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) static void rk816_bat_zero_algorithm(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 	int delta_cap = 0, delta_soc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 	di->zero_timeout_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 	delta_cap = di->zero_remain_cap - di->remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 	delta_soc = di->zero_linek * (delta_cap * 100) / DIV(di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 	DBG("ZERO1: zero_linek=%d, zero_dsoc(Y0)=%d, dsoc=%d, rsoc=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 	    "ZERO1: delta_soc(X0)=%d, delta_cap=%d, zero_remain_cap = %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 	    "ZERO1: timeout_cnt=%d, sm_dischrg=%d, sm_chrg=%d\n\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 	    di->zero_linek, di->zero_dsoc, di->dsoc, di->rsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 	    delta_soc, delta_cap, di->zero_remain_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 	    di->zero_timeout_cnt, di->sm_dischrg_dsoc, di->sm_chrg_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 	if ((delta_soc >= MIN_ZERO_DSOC_ACCURACY) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 	    (di->zero_timeout_cnt > MIN_ZERO_OVERCNT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 	    (di->zero_linek == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 		DBG("ZERO1:--------- enter calc -----------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 		di->zero_timeout_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 		di->zero_dsoc -= delta_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 		rk816_bat_calc_zero_algorithm(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 		rk816_bat_calc_zero_linek(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) static void rk816_bat_dump_time_table(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 	u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 	static int old_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 	static int old_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 	u32 time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 	int mod = di->dsoc % 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 	int index = di->dsoc / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 	if (rk816_bat_chrg_online(di))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 		time = base2min(di->plug_in_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 		time = base2min(di->plug_out_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 	if ((mod == 0) && (index > 0) && (old_index != index)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 		di->dbg_chrg_min[index - 1] = time - old_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 		old_min = time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 		old_index = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 	for (i = 1; i < 11; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 		DBG("Time[%d]=%d, ", (i * 10), di->dbg_chrg_min[i - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 	DBG("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) static void rk816_bat_debug_info(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 	u8 sup_tst, ggcon, ggsts, vb_mod, ts_ctrl, reboot_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 	u8 usb_ctrl, chrg_ctrl1, thermal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 	u8 int_sts1, int_sts2, int_sts3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 	u8 int_msk1, int_msk2, int_msk3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 	u8 chrg_ctrl2, chrg_ctrl3, rtc, misc, dcdc_en2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 	u32 chrg_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 	const char *work_mode[] = {"ZERO", "FINISH", "UN", "UN", "SMOOTH"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 	const char *bat_mode[] = {"BAT", "VIRTUAL"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 	if (rk816_bat_chrg_online(di))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 		di->plug_out_base = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 		di->plug_in_base = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 	rk816_bat_dump_time_table(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 	if (!dbg_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 	reboot_cnt = rk816_bat_read(di, RK816_REBOOT_CNT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 	ts_ctrl = rk816_bat_read(di, RK816_TS_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 	misc = rk816_bat_read(di, RK816_MISC_MARK_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 	ggcon = rk816_bat_read(di, RK816_GGCON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 	ggsts = rk816_bat_read(di, RK816_GGSTS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 	sup_tst = rk816_bat_read(di, RK816_SUP_STS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 	vb_mod = rk816_bat_read(di, RK816_VB_MON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 	usb_ctrl = rk816_bat_read(di, RK816_USB_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 	chrg_ctrl1 = rk816_bat_read(di, RK816_CHRG_CTRL_REG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 	chrg_ctrl2 = rk816_bat_read(di, RK816_CHRG_CTRL_REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 	chrg_ctrl3 = rk816_bat_read(di, RK816_CHRG_CTRL_REG3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 	rtc = rk816_bat_read(di, RK808_SECONDS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 	thermal = rk816_bat_read(di, RK816_THERMAL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 	int_sts1 = rk816_bat_read(di, RK816_INT_STS_REG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 	int_sts2 = rk816_bat_read(di, RK816_INT_STS_REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 	int_sts3 = rk816_bat_read(di, RK816_INT_STS_REG3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 	int_msk1 = rk816_bat_read(di, RK816_INT_STS_MSK_REG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 	int_msk2 = rk816_bat_read(di, RK816_INT_STS_MSK_REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 	int_msk3 = rk816_bat_read(di, RK816_INT_STS_MSK_REG3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 	dcdc_en2 = rk816_bat_read(di, RK816_DCDC_EN_REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 	chrg_sel = CHRG_CUR_SEL[chrg_ctrl1 & 0x0f];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 	if (!di->over_20mR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 		chrg_sel = RES_FAC_MUX(chrg_sel, di->res_fac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 		chrg_sel = RES_FAC_DIV(chrg_sel, di->res_fac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 	DBG("\n------- DEBUG REGS, [Ver: %s] -------------------\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 	    "GGCON=0x%2x, GGSTS=0x%2x, RTC=0x%2x, DCDC_EN2=0x%2x\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 	    "SUP_STS= 0x%2x, VB_MOD=0x%2x, USB_CTRL=0x%2x\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 	    "THERMAL=0x%2x, MISC_MARK=0x%2x, TS_CTRL=0x%2x\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 	    "CHRG_CTRL:REG1=0x%2x, REG2=0x%2x, REG3=0x%2x\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 	    "INT_STS:  REG1=0x%2x, REG2=0x%2x, REG3=0x%2x\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 	    "INT_MSK:  REG1=0x%2x, REG2=0x%2x, REG3=0x%2x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 	    DRIVER_VERSION, ggcon, ggsts, rtc, dcdc_en2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 	    sup_tst, vb_mod, usb_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 	    thermal, misc, ts_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 	    chrg_ctrl1, chrg_ctrl2, chrg_ctrl3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 	    int_sts1, int_sts2, int_sts3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 	    int_msk1, int_msk2, int_msk3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 	   );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 	DBG("###############################################################\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 	    "Dsoc=%d, Rsoc=%d, Vavg=%d, Iavg=%d, Cap=%d, Fcc=%d, d=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 	    "K=%d, Mode=%s, Oldcap=%d, Is=%d, Ip=%d, Vs=%d, Vusb=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 	    "AC=%d, USB=%d, DC=%d, OTG=%d, 5V=%d, PROP=%d, Tfb=%d, Tbat=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 	    "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 2845) 	    "adp:in=%lu, out=%lu, finish=%lu, LFcc=%d, boot_min=%lu, sleep_min=%lu, adc=%d, Rfac=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 	    "bat:%s, meet: soc=%d, calc: dsoc=%d, rsoc=%d, Vocv=%d, Rsam=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 	    "pwr: dsoc=%d, rsoc=%d, vol=%d, halt: st=%d, cnt=%d, reboot=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 	    "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 2849) 	    "min=%d, init=%d, sw=%d, below0=%d, first=%d, changed=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 	    "###############################################################\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 	    di->dsoc, di->rsoc, di->voltage_avg, di->current_avg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 	    di->remain_cap, di->fcc, di->dsoc - di->rsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 	    di->sm_linek, work_mode[di->work_mode], di->sm_remain_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 	    chrg_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 	    CHRG_CUR_INPUT[usb_ctrl & 0x0f],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 	    CHRG_VOL_SEL[(chrg_ctrl1 & 0x70) >> 4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 	    rk816_bat_get_usb_voltage(di),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 	    di->ac_in, di->usb_in, di->dc_in, di->otg_in, di->otg_pmic5v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 	    di->prop_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 	    FEED_BACK_TEMP[(thermal & 0x0c) >> 2], di->temperature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 	    rk816_bat_get_ioffset(di), rk816_bat_get_coffset(di),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 	    di->poffset, di->bat_res, di->age_adjust_cap, di->fb_blank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 	    !!(thermal & HOTDIE_STS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 	    base2min(di->plug_in_base), base2min(di->plug_out_base),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 	    base2min(di->chrg_finish_base), di->lock_fcc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 	    base2min(di->boot_base), di->sleep_sum_sec / 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 	    di->adc_allow_update, di->res_fac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 	    bat_mode[di->pdata->bat_mode], di->dbg_meet_soc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 	    di->dbg_calc_dsoc, di->dbg_calc_rsoc, di->voltage_ocv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 	    di->pdata->sample_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 	    di->dbg_pwr_dsoc, di->dbg_pwr_rsoc, di->dbg_pwr_vol, di->is_halt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 	    di->halt_cnt, reboot_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 	    di->is_ocv_calib, di->ocv_pre_dsoc, di->ocv_new_dsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 	    di->is_max_soc_offset, di->max_pre_dsoc, di->max_new_dsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 	    di->is_force_calib, di->force_pre_dsoc, di->force_new_dsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 	    di->pwroff_min, di->is_initialized, di->is_sw_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 	    di->dbg_cap_low0, di->is_first_on, di->last_dsoc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 	   );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) static void rk816_bat_init_capacity(struct rk816_battery *di, u32 cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 	int delta_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 	delta_cap = cap - di->remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 	if (!delta_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 	di->age_adjust_cap += delta_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 	rk816_bat_init_coulomb_cap(di, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 	rk816_bat_smooth_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 	rk816_bat_zero_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) static void rk816_bat_update_age_fcc(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 	int fcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 	int remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 	int age_keep_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 	di->lock_fcc = rk816_bat_get_lock_fcc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 	if (di->lock_fcc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 	fcc = di->lock_fcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 	remain_cap = fcc - di->age_ocv_cap - di->age_adjust_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 	age_keep_min = base2min(di->age_keep_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 	DBG("%s: lock_fcc=%d, age_ocv_cap=%d, age_adjust_cap=%d, remain_cap=%d, age_allow_update=%d, age_keep_min=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 	    __func__, fcc, di->age_ocv_cap, di->age_adjust_cap, remain_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 	    di->age_allow_update, age_keep_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 	if ((di->chrg_status == CHARGE_FINISH) && (di->age_allow_update) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 	    (age_keep_min < 1200)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 		di->age_allow_update = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 		fcc = remain_cap * 100 / DIV(100 - di->age_ocv_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 		BAT_INFO("lock_fcc=%d, calc_cap=%d, age: soc=%d, cap=%d, level=%d, fcc:%d->%d?\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 			 di->lock_fcc, remain_cap, di->age_ocv_soc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 			 di->age_ocv_cap, di->age_level, di->fcc, fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 		if ((fcc < di->qmax) && (fcc > MIN_FCC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 			BAT_INFO("fcc:%d->%d!\n", di->fcc, fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 			di->fcc = fcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 			rk816_bat_init_capacity(di, di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 			rk816_bat_save_fcc(di, di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 			rk816_bat_save_age_level(di, di->age_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) static void rk816_bat_wait_finish_sig(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 	int chrg_finish_vol = di->pdata->max_chrg_voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 	if (!rk816_bat_chrg_online(di))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 	if ((di->chrg_status == CHARGE_FINISH) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 	    (!is_rk816_bat_st_cvtlim(di)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 	    (di->voltage_avg > chrg_finish_vol - 150) && di->adc_allow_update) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 		rk816_bat_update_age_fcc(di);/* save new fcc*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 		if (rk816_bat_adc_calib(di))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 			di->adc_allow_update = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) static void rk816_bat_finish_algorithm(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) 	unsigned long finish_sec, soc_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 	int plus_soc, finish_current, rest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 	/* rsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 	if ((di->remain_cap != di->fcc) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 	    (rk816_bat_get_chrg_status(di) == CHARGE_FINISH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 		di->age_adjust_cap += (di->fcc - di->remain_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 		rk816_bat_init_coulomb_cap(di, di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 	/* dsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 	if (di->dsoc < 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 		if (!di->chrg_finish_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 			di->chrg_finish_base = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 		finish_current = (di->rsoc - di->dsoc) >  FINISH_MAX_SOC_DELAY ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 					FINISH_CHRG_CUR2 : FINISH_CHRG_CUR1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 		finish_sec = base2sec(di->chrg_finish_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 		soc_sec = di->fcc * 3600 / 100 / DIV(finish_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 		plus_soc = finish_sec / DIV(soc_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 		if (finish_sec > soc_sec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 			rest = finish_sec % soc_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 			di->dsoc += plus_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) 			di->chrg_finish_base = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 			if (di->chrg_finish_base > rest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 				di->chrg_finish_base = get_boot_sec() - rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 		DBG("<%s>.CHARGE_FINISH:dsoc<100,dsoc=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 		    "soc_time=%lu, sec_finish=%lu, plus_soc=%d, rest=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 		    __func__, di->dsoc, soc_sec, finish_sec, plus_soc, rest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) static void rk816_bat_calc_smooth_dischrg(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 	int tmp_soc = 0, sm_delta_dsoc = 0, zero_delta_dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 	tmp_soc = di->sm_dischrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 	if (tmp_soc == di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 	DBG("<%s>. enter: dsoc=%d, rsoc=%d\n", __func__, di->dsoc, di->rsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 	/* when dischrge slow down, take sm charge rest into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 	if (di->dsoc < di->rsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 		tmp_soc = di->sm_chrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 		if (tmp_soc == di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 			sm_delta_dsoc = di->sm_chrg_dsoc - di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 			di->sm_chrg_dsoc = di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 			di->sm_dischrg_dsoc += sm_delta_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 			DBG("<%s>. take sm dischrg, delta=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 			    __func__, sm_delta_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 	/* when discharge speed up, take zero discharge rest into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 	if (di->dsoc > di->rsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 		tmp_soc = di->zero_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 		if (tmp_soc == di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 			zero_delta_dsoc = di->zero_dsoc - ((di->dsoc + 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 						1000 - MIN_ACCURACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 			di->zero_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 			di->sm_dischrg_dsoc += zero_delta_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 			DBG("<%s>. take zero schrg, delta=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 			    __func__, zero_delta_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 		}
^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 up overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 	if ((di->sm_dischrg_dsoc) > ((di->dsoc + 1) * 1000 - MIN_ACCURACY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 		DBG("<%s>. dischrg_dsoc up overflow\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 		di->sm_dischrg_dsoc = (di->dsoc + 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 					1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 	/* check new dsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 	tmp_soc = di->sm_dischrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 	if (tmp_soc != di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 		di->dsoc = tmp_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 		di->sm_chrg_dsoc = di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 	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 3031) 	    __func__, di->dsoc, di->rsoc, di->sm_dischrg_dsoc, di->sm_chrg_dsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 	    di->zero_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) static void rk816_bat_calc_smooth_chrg(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 	int tmp_soc = 0, sm_delta_dsoc = 0, zero_delta_dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) 	tmp_soc = di->sm_chrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 	if (tmp_soc == di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 	DBG("<%s>. enter: dsoc=%d, rsoc=%d\n", __func__, di->dsoc, di->rsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 	/* when charge slow down, take zero & sm dischrg into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 	if (di->dsoc > di->rsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) 		/* take sm discharge rest into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 		tmp_soc = di->sm_dischrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) 		if (tmp_soc == di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 			sm_delta_dsoc = di->sm_dischrg_dsoc -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 					((di->dsoc + 1) * 1000 - MIN_ACCURACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 			di->sm_dischrg_dsoc = (di->dsoc + 1) * 1000 -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 							MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 			di->sm_chrg_dsoc += sm_delta_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 			DBG("<%s>. take sm dischrg, delta=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 			    __func__, sm_delta_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 		/* take zero discharge rest into calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 		tmp_soc = di->zero_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 		if (tmp_soc == di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 			zero_delta_dsoc = di->zero_dsoc -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 			((di->dsoc + 1) * 1000 - MIN_ACCURACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 			di->zero_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 			di->sm_chrg_dsoc += zero_delta_dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 			DBG("<%s>. take zero dischrg, delta=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 			    __func__, zero_delta_dsoc);
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) 	/* check down overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 	if (di->sm_chrg_dsoc < di->dsoc * 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 		DBG("<%s>. chrg_dsoc down overflow\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) 		di->sm_chrg_dsoc = di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 	/* check new dsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 	tmp_soc = di->sm_chrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 	if (tmp_soc != di->dsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 		di->dsoc = tmp_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 		di->sm_dischrg_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 	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 3084) 	    __func__, di->dsoc, di->rsoc, di->sm_dischrg_dsoc, di->sm_chrg_dsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 	    di->zero_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) static void rk816_bat_smooth_algorithm(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 	int ydsoc = 0, delta_cap = 0, old_cap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 	unsigned long tgt_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 	di->remain_cap = rk816_bat_get_coulomb_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 	/* full charge: slow down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 	if ((di->dsoc == 99) && (di->chrg_status == CC_OR_CV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 	    (di->current_avg > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 		di->sm_linek = FULL_CHRG_K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 	/* terminal charge, slow down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 	} else if ((di->current_avg >= TERM_CHRG_CURR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 	    (di->chrg_status == CC_OR_CV) && (di->dsoc >= TERM_CHRG_DSOC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 		di->sm_linek = TERM_CHRG_K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 		DBG("<%s>. terminal mode..\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 	/* simulate charge, speed up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 	} else if ((di->current_avg <= SIMULATE_CHRG_CURR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 		   (di->current_avg > 0) && (di->chrg_status == CC_OR_CV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 		   (di->dsoc < TERM_CHRG_DSOC) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 		   ((di->rsoc - di->dsoc) >= SIMULATE_CHRG_INTV)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 		di->sm_linek = SIMULATE_CHRG_K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 		DBG("<%s>. simulate mode..\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 		/* charge and discharge switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 		if ((di->sm_linek * di->current_avg <= 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 		    (di->sm_linek == TERM_CHRG_K) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 		    (di->sm_linek == FULL_CHRG_K) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 		    (di->sm_linek == SIMULATE_CHRG_K)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 			DBG("<%s>. linek mode, retinit sm linek..\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 			rk816_bat_calc_sm_linek(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 	old_cap = di->sm_remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 	 * when dsoc equal rsoc(not include full, term, simulate case),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 	 * sm_linek should change to -1000/1000 smoothly to avoid dsoc+1/-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 	 * right away, so change it after flat seconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 	if ((di->dsoc == di->rsoc) && (abs(di->sm_linek) != 1000) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 	    (di->sm_linek != FULL_CHRG_K && di->sm_linek != TERM_CHRG_K &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 	     di->sm_linek != SIMULATE_CHRG_K)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 		if (!di->flat_match_sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 			di->flat_match_sec = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 		tgt_sec = di->fcc * 3600 / 100 / DIV(abs(di->current_avg)) / 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 		if (base2sec(di->flat_match_sec) >= tgt_sec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 			di->flat_match_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 			di->sm_linek = (di->current_avg >= 0) ? 1000 : -1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 		DBG("<%s>. flat_sec=%ld, tgt_sec=%ld, sm_k=%d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 		    base2sec(di->flat_match_sec), tgt_sec, di->sm_linek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 		di->flat_match_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 	/* abs(k)=1000 or dsoc=100, stop calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 	if ((abs(di->sm_linek) == 1000) || (di->current_avg >= 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 	     di->chrg_status == CC_OR_CV && di->dsoc >= 100)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 		DBG("<%s>. sm_linek=%d\n", __func__, di->sm_linek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 		if (abs(di->sm_linek) == 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 			di->dsoc = di->rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 			di->sm_linek = (di->sm_linek > 0) ? 1000 : -1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 			DBG("<%s>. dsoc == rsoc, sm_linek=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 			    __func__, di->sm_linek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 		di->sm_remain_cap = di->remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 		di->sm_chrg_dsoc = di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 		di->sm_dischrg_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 		DBG("<%s>. sm_dischrg_dsoc=%d, sm_chrg_dsoc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 		    __func__, di->sm_dischrg_dsoc, di->sm_chrg_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 		delta_cap = di->remain_cap - di->sm_remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 		if (delta_cap == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 			DBG("<%s>. delta_cap = 0\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 		ydsoc = di->sm_linek * abs(delta_cap) * 100 / DIV(di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 		if (ydsoc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 			DBG("<%s>. ydsoc = 0\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) 		di->sm_remain_cap = di->remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 		DBG("<%s>. k=%d, ydsoc=%d; cap:old=%d, new:%d; delta_cap=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) 		    __func__, di->sm_linek, ydsoc, old_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) 		    di->sm_remain_cap, delta_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 		/* discharge mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 		if (ydsoc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 			di->sm_dischrg_dsoc += ydsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 			rk816_bat_calc_smooth_dischrg(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 		/* charge mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 			di->sm_chrg_dsoc += ydsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 			rk816_bat_calc_smooth_chrg(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 		if (di->s2r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 			di->s2r = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 			rk816_bat_calc_sm_linek(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) static bool rk816_bat_fake_finish_mode(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 	if ((di->rsoc == 100) && (rk816_bat_get_chrg_status(di) == CC_OR_CV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 	    (abs(di->current_avg) <= 100))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) static void rk816_bat_display_smooth(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 	/* discharge: reinit "zero & smooth" algorithm to avoid handling dsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 	if (di->s2r && !di->sleep_chrg_online) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 		DBG("s2r: discharge, reset algorithm...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 		di->s2r = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 		rk816_bat_zero_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 		rk816_bat_smooth_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 	if (di->work_mode == MODE_FINISH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 		DBG("step1: charge finish...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 		rk816_bat_finish_algorithm(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 		if ((rk816_bat_get_chrg_status(di) != CHARGE_FINISH) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 		    !rk816_bat_fake_finish_mode(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 			if ((di->current_avg < 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) 			    (di->voltage_avg < di->pdata->zero_algorithm_vol)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) 				DBG("step1: change to zero mode...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) 				rk816_bat_zero_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) 				di->work_mode = MODE_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) 				DBG("step1: change to smooth mode...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 				rk816_bat_smooth_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) 				di->work_mode = MODE_SMOOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) 	} else if (di->work_mode == MODE_ZERO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 		DBG("step2: zero algorithm...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) 		rk816_bat_zero_algorithm(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) 		if ((di->voltage_avg >= di->pdata->zero_algorithm_vol + 50) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) 		    (di->current_avg >= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) 			DBG("step2: change to smooth mode...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) 			rk816_bat_smooth_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 			di->work_mode = MODE_SMOOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) 		} else if ((rk816_bat_get_chrg_status(di) == CHARGE_FINISH) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 			   rk816_bat_fake_finish_mode(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) 			DBG("step2: change to finish mode...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) 			rk816_bat_finish_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) 			di->work_mode = MODE_FINISH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) 		DBG("step3: smooth algorithm...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 		rk816_bat_smooth_algorithm(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 		if ((di->current_avg < 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 		    (di->voltage_avg < di->pdata->zero_algorithm_vol)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 			DBG("step3: change to zero mode...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 			rk816_bat_zero_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 			di->work_mode = MODE_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) 		} else if ((rk816_bat_get_chrg_status(di) == CHARGE_FINISH) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 			   rk816_bat_fake_finish_mode(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 			DBG("step3: change to finish mode...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 			rk816_bat_finish_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 			di->work_mode = MODE_FINISH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) static void rk816_bat_relax_vol_calib(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 	int soc, cap, vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 	vol = di->voltage_relax - (di->current_relax * di->bat_res) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 	soc = rk816_bat_vol_to_ocvsoc(di, vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 	cap = rk816_bat_vol_to_ocvcap(di, vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 	rk816_bat_init_capacity(di, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 	BAT_INFO("sleep ocv calib: rsoc=%d, cap=%d\n", soc, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) static void rk816_bat_relife_age_flag(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) 	u8 ocv_soc, ocv_cap, soc_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 	if (di->voltage_relax <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 	ocv_soc = rk816_bat_vol_to_ocvsoc(di, di->voltage_relax);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) 	ocv_cap = rk816_bat_vol_to_ocvcap(di, di->voltage_relax);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) 	DBG("<%s>. ocv_soc=%d, min=%lu, vol=%d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 	    ocv_soc, di->sleep_dischrg_sec / 60, di->voltage_relax);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 	/* sleep enough time and ocv_soc enough low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 	if (!di->age_allow_update && ocv_soc <= 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 		di->age_voltage = di->voltage_relax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 		di->age_ocv_cap = ocv_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 		di->age_ocv_soc = ocv_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 		di->age_adjust_cap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 		if (ocv_soc <= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 			di->age_level = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 		else if (ocv_soc < 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 			di->age_level = 90;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) 			di->age_level = 80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) 		soc_level = rk816_bat_get_age_level(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) 		if (soc_level > di->age_level) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 			di->age_allow_update = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 			di->age_allow_update = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 			di->age_keep_sec = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) 		BAT_INFO("resume: age_vol:%d, age_ocv_cap:%d, age_ocv_soc:%d, age_soc_level:%d, age_allow_update:%d, age_level:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) 			 di->age_voltage, di->age_ocv_cap, ocv_soc, soc_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 			 di->age_allow_update, di->age_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) static int rk816_bat_sleep_dischrg(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 	bool ocv_soc_updated = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) 	int tgt_dsoc, gap_soc, sleep_soc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 	int pwroff_vol = di->pdata->pwroff_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) 	unsigned long sleep_sec = di->sleep_dischrg_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) 	DBG("<%s>. enter: dsoc=%d, rsoc=%d, rv=%d, v=%d, sleep_min=%lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) 	    __func__, di->dsoc, di->rsoc, di->voltage_relax,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) 	    di->voltage_avg, sleep_sec / 60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) 	if (di->voltage_relax >= di->voltage_avg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) 		rk816_bat_relax_vol_calib(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) 		rk816_bat_restart_relax(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) 		rk816_bat_relife_age_flag(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) 		ocv_soc_updated = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) 	/*handle dsoc*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) 	if (di->dsoc <= di->rsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) 		di->sleep_sum_cap = (SLP_CURR_MIN * sleep_sec / 3600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) 		sleep_soc = di->sleep_sum_cap * 100 / DIV(di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) 		tgt_dsoc = di->dsoc - sleep_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) 		if (sleep_soc > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) 			BAT_INFO("calib0: rl=%d, dl=%d, intval=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) 				 di->rsoc, di->dsoc, sleep_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 			if (di->dsoc < 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) 				di->dsoc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) 			} else if ((tgt_dsoc < 5) && (di->dsoc >= 5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) 				if (di->dsoc == 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) 					di->dsoc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) 					di->dsoc = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) 			} else if (tgt_dsoc > 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) 				di->dsoc = tgt_dsoc;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) 		DBG("%s: dsoc<=rsoc, sum_cap=%d==>sleep_soc=%d, tgt_dsoc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) 		    __func__, di->sleep_sum_cap, sleep_soc, tgt_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 		/*di->dsoc > di->rsoc*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) 		di->sleep_sum_cap = (SLP_CURR_MAX * sleep_sec / 3600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) 		sleep_soc = di->sleep_sum_cap / DIV(di->fcc / 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) 		gap_soc = di->dsoc - di->rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) 		BAT_INFO("calib1: rsoc=%d, dsoc=%d, intval=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) 			 di->rsoc, di->dsoc, sleep_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) 		if (gap_soc > sleep_soc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) 			if ((gap_soc - 5) > (sleep_soc * 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) 				di->dsoc -= (sleep_soc * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 				di->dsoc -= sleep_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 			di->dsoc = di->rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 		DBG("%s: dsoc>rsoc, sum_cap=%d=>sleep_soc=%d, gap_soc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 		    __func__, di->sleep_sum_cap, sleep_soc, gap_soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 	if (di->voltage_avg <= pwroff_vol - 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 		di->dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) 		rk_send_wakeup_key();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 		BAT_INFO("low power sleeping, shutdown... %d\n", di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) 	if (ocv_soc_updated && sleep_soc && (di->rsoc - di->dsoc) < 5 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) 	    di->dsoc < 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) 		di->dsoc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) 		BAT_INFO("low power sleeping, reserved... %d\n", di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) 	if (di->dsoc <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) 		di->dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) 		rk_send_wakeup_key();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) 		BAT_INFO("sleep dsoc is %d...\n", di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) 	DBG("<%s>. out: dsoc=%d, rsoc=%d, sum_cap=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) 	    __func__, di->dsoc, di->rsoc, di->sleep_sum_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) 	return sleep_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) static void rk816_bat_power_supply_changed(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) 	u8 status, thermal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) 	static int old_soc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) 	/* check dsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) 	if (di->dsoc > 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) 		di->dsoc = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) 	else if (di->dsoc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) 		di->dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) 	/* update prop and leds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) 	if (rk816_bat_chrg_online(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) 		if (di->dsoc == 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) 			di->prop_status = POWER_SUPPLY_STATUS_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) 			di->prop_status = POWER_SUPPLY_STATUS_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) 		rk816_bat_update_leds(di, di->prop_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) 	if (di->dsoc == old_soc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) 	/* report changed dsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) 	thermal = rk816_bat_read(di, RK816_THERMAL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) 	status = rk816_bat_read(di, RK816_SUP_STS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) 	status = (status & CHRG_STATUS_MSK) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) 	old_soc = di->dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) 	di->last_dsoc = di->dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) 	power_supply_changed(di->bat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) 	BAT_INFO("changed: dsoc=%d, rsoc=%d, v=%d, ov=%d c=%d, cap=%d, f=%d, st=%s, hotdie=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) 		 di->dsoc, di->rsoc, di->voltage_avg, di->voltage_ocv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) 		 di->current_avg, di->remain_cap, di->fcc, bat_status[status],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) 		 !!(thermal & HOTDIE_STS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) 	BAT_INFO("dl=%d, rl=%d, v=%d, halt=%d, halt_n=%d, max=%d, init=%d, sw=%d, calib=%d, below0=%d, force=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) 		 di->dbg_pwr_dsoc, di->dbg_pwr_rsoc, di->dbg_pwr_vol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) 		 di->is_halt, di->halt_cnt, di->is_max_soc_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) 		 di->is_initialized, di->is_sw_reset, di->is_ocv_calib,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) 		 di->dbg_cap_low0, di->is_force_calib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) static u8 rk816_bat_check_reboot(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) 	u8 cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) 	cnt = rk816_bat_read(di, RK816_REBOOT_CNT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) 	cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) 	if (cnt >= REBOOT_MAX_CNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) 		BAT_INFO("reboot: %d --> %d\n", di->dsoc, di->rsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) 		di->dsoc = di->rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) 		if (di->dsoc > 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) 			di->dsoc = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) 		else if (di->dsoc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) 			di->dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) 		rk816_bat_save_dsoc(di, di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 		cnt = REBOOT_MAX_CNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) 	rk816_bat_save_reboot_cnt(di, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) 	DBG("reboot cnt: %d\n", cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) 	return cnt;
^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 void rk816_bat_check_charger(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) 	buf = rk816_bat_read(di, RK816_VB_MON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) 	/* pmic detect plug in, but ac/usb/dc_in offline, do check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) 	if ((buf & PLUG_IN_STS) != 0 && !rk816_bat_chrg_online(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) 		rk816_bat_set_chrg_param(di, USB_TYPE_USB_CHARGER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) 		BAT_INFO("pmic detect charger.. USB\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) 	/* pmic not detect plug in, but one of ac/usb/dc_in online, reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) 	} else if ((buf & PLUG_IN_STS) == 0 && rk816_bat_chrg_online(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) 		rk816_bat_set_chrg_param(di, USB_TYPE_UNKNOWN_CHARGER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) 		BAT_INFO("pmic not detect charger..\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) static void rk816_bat_rsoc_daemon(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) 	int est_vol, remain_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) 	static unsigned long sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) 	if ((di->remain_cap < 0) && (di->fb_blank != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) 		if (!sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) 			sec = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) 		wake_lock_timeout(&di->wake_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) 				  (di->pdata->monitor_sec + 1) * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) 		DBG("sec=%ld, hold_sec=%ld\n", sec, base2sec(sec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) 		if (base2sec(sec) >= 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) 			sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) 			di->dbg_cap_low0++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) 			est_vol = di->voltage_avg -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) 					(di->bat_res * di->current_avg) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) 			remain_cap = rk816_bat_vol_to_ocvcap(di, est_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) 			rk816_bat_init_capacity(di, remain_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) 			BAT_INFO("adjust cap below 0 --> %d, rsoc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) 				 di->remain_cap, di->rsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) 			wake_unlock(&di->wake_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) 		sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) static void rk816_bat_update_info(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) 	bool is_charging;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) 	di->voltage_avg = rk816_bat_get_avg_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) 	di->current_avg = rk816_bat_get_avg_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) 	di->chrg_status = rk816_bat_get_chrg_status(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) 	di->voltage_relax = rk816_bat_get_relax_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) 	di->rsoc = rk816_bat_get_rsoc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) 	di->remain_cap = rk816_bat_get_coulomb_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) 	is_charging = rk816_bat_chrg_online(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) 	if (is_charging != di->is_charging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) 		di->is_charging = is_charging;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) 		if (is_charging)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) 			di->charge_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) 	if (di->voltage_avg > di->voltage_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) 		di->voltage_max = di->voltage_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) 	if (di->current_avg > di->current_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) 		di->current_max = di->current_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) 	/* smooth charge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) 	if (di->remain_cap > di->fcc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) 		di->sm_remain_cap -= (di->remain_cap - di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) 		DBG("<%s>. cap: remain=%d, sm_remain=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) 		    __func__, di->remain_cap, di->sm_remain_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) 		rk816_bat_init_coulomb_cap(di, di->fcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) 	if (di->chrg_status != CHARGE_FINISH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) 		di->chrg_finish_base = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) 	 * we need update fcc in continuous charging state, if discharge state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) 	 * keep at least 2 hour, we decide not to update fcc, so clear the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 	 * fcc update flag: age_allow_update.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) 	if (base2min(di->plug_out_base) > 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) 		di->age_allow_update = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) 	/* do adc calib: status must from cccv mode to finish mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) 	if (di->chrg_status == CC_OR_CV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) 		di->adc_allow_update = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) 		di->adc_calib_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) static void rk816_bat_init_dsoc_algorithm(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) 	int16_t rest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) 	unsigned long soc_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) 	const char *mode_name[] = { "MODE_ZERO", "MODE_FINISH",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) 		"MODE_SMOOTH_CHRG", "MODE_SMOOTH_DISCHRG", "MODE_SMOOTH", };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) 	/* get rest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) 	rest |= rk816_bat_read(di, RK816_CALC_REST_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) 	rest |= rk816_bat_read(di, RK816_CALC_REST_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) 	/* get mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) 	buf = rk816_bat_read(di, RK816_MISC_MARK_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) 	di->algo_rest_mode = (buf & ALGO_REST_MODE_MSK) >> ALGO_REST_MODE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) 	if (rk816_bat_get_chrg_status(di) == CHARGE_FINISH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) 		if (di->algo_rest_mode == MODE_FINISH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) 			soc_sec = di->fcc * 3600 / 100 / FINISH_CHRG_CUR1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) 			if ((rest / DIV(soc_sec)) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) 				if (di->dsoc < 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) 					di->dsoc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) 					di->algo_rest_val = rest % soc_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) 					BAT_INFO("algorithm rest(%d) dsoc inc: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) 						 rest, di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) 					di->algo_rest_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) 				di->algo_rest_val = rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) 			di->algo_rest_val = rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 		buf = rk816_bat_read(di, RK816_VB_MON_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) 		/* charge speed up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 		if ((rest / 1000) > 0 && (buf & PLUG_IN_STS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) 			if (di->dsoc < di->rsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) 				di->dsoc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) 				di->algo_rest_val = rest % 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) 				BAT_INFO("algorithm rest(%d) dsoc inc: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) 					 rest, di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) 				di->algo_rest_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) 		/* discharge speed up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) 		} else if (((rest / 1000) < 0) && !(buf & PLUG_IN_STS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) 			if (di->dsoc > di->rsoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) 				di->dsoc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) 				di->algo_rest_val = rest % 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) 				BAT_INFO("algorithm rest(%d) dsoc sub: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) 					 rest, di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) 				di->algo_rest_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) 			di->algo_rest_val = rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) 	if (di->dsoc >= 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) 		di->dsoc = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) 	else if (di->dsoc <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) 		di->dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) 	/* init current mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) 	di->voltage_avg = rk816_bat_get_avg_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) 	di->current_avg = rk816_bat_get_avg_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) 	if (rk816_bat_get_chrg_status(di) == CHARGE_FINISH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) 		rk816_bat_finish_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) 		di->work_mode = MODE_FINISH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) 		rk816_bat_smooth_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) 		di->work_mode = MODE_SMOOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) 	DBG("<%s>. init: org_rest=%d, rest=%d, mode=%s; "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) 	    "doc(x1000): zero=%d, chrg=%d, dischrg=%d, finish=%lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) 	    __func__, rest, di->algo_rest_val, mode_name[di->algo_rest_mode],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) 	    di->zero_dsoc, di->sm_chrg_dsoc, di->sm_dischrg_dsoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) 	    di->chrg_finish_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) static void rk816_bat_save_algo_rest(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) 	u8 buf, mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) 	int16_t algo_rest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) 	int tmp_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) 	int zero_rest = 0, sm_chrg_rest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) 	int sm_dischrg_rest = 0, finish_rest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) 	static const char *mode_name[] = { "MODE_ZERO", "MODE_FINISH",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) 		"MODE_SMOOTH_CHRG", "MODE_SMOOTH_DISCHRG", "MODE_SMOOTH", };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) 	/* zero dischrg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) 	tmp_soc = (di->zero_dsoc) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) 	if (tmp_soc == di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) 		zero_rest = di->zero_dsoc - ((di->dsoc + 1) * 1000 -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) 				MIN_ACCURACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) 	/* sm chrg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) 	tmp_soc = di->sm_chrg_dsoc / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) 	if (tmp_soc == di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) 		sm_chrg_rest = di->sm_chrg_dsoc - di->dsoc * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) 	/* sm dischrg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) 	tmp_soc = (di->sm_dischrg_dsoc) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) 	if (tmp_soc == di->dsoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) 		sm_dischrg_rest = di->sm_dischrg_dsoc - ((di->dsoc + 1) * 1000 -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) 				MIN_ACCURACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) 	/* last time is also finish chrg, then add last rest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) 	if (di->algo_rest_mode == MODE_FINISH && di->algo_rest_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) 		finish_rest = base2sec(di->chrg_finish_base) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) 			      di->algo_rest_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) 		finish_rest = base2sec(di->chrg_finish_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) 	/* total calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) 	if ((rk816_bat_chrg_online(di) && (di->dsoc > di->rsoc)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) 	    (!rk816_bat_chrg_online(di) && (di->dsoc < di->rsoc)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) 	    (di->dsoc == di->rsoc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) 		di->algo_rest_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) 		algo_rest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) 		DBG("<%s>. step1..\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) 	} else if (di->work_mode == MODE_FINISH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) 		algo_rest = finish_rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) 		DBG("<%s>. step2..\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) 	} else if (di->algo_rest_mode == MODE_FINISH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) 		algo_rest = zero_rest + sm_dischrg_rest + sm_chrg_rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) 		DBG("<%s>. step3..\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) 		if (rk816_bat_chrg_online(di) && (di->dsoc < di->rsoc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) 			algo_rest = sm_chrg_rest + di->algo_rest_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) 		else if (!rk816_bat_chrg_online(di) && (di->dsoc > di->rsoc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) 			algo_rest = zero_rest + sm_dischrg_rest +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) 				    di->algo_rest_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) 			algo_rest = zero_rest + sm_dischrg_rest + sm_chrg_rest +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) 				    di->algo_rest_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) 		DBG("<%s>. step4..\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) 	/* check mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) 	if ((di->work_mode == MODE_FINISH) || (di->work_mode == MODE_ZERO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) 		mode = di->work_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) 	} else {/* MODE_SMOOTH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) 		if (di->sm_linek > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) 			mode = MODE_SMOOTH_CHRG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) 			mode = MODE_SMOOTH_DISCHRG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) 	/* save mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) 	buf = rk816_bat_read(di, RK816_MISC_MARK_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) 	buf &= ~ALGO_REST_MODE_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) 	buf |= (mode << ALGO_REST_MODE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) 	rk816_bat_write(di, RK816_MISC_MARK_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) 	/* save rest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) 	buf = (algo_rest >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) 	rk816_bat_write(di, RK816_CALC_REST_REGH, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) 	buf = (algo_rest >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) 	rk816_bat_write(di, RK816_CALC_REST_REGL, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) 	DBG("<%s>. rest: algo=%d, mode=%s, last_rest=%d; zero=%d, chrg=%d, dischrg=%d, finish=%lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) 	    __func__, algo_rest, mode_name[mode], di->algo_rest_val, zero_rest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) 	    sm_chrg_rest, sm_dischrg_rest, base2sec(di->chrg_finish_base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) static void rk816_bat_save_data(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) 	rk816_bat_save_dsoc(di, di->dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) 	rk816_bat_save_cap(di, di->remain_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) 	rk816_bat_save_algo_rest(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) /*get ntc resistance*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) static int rk816_bat_get_ntc_res(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) 	int res, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) 	val |= rk816_bat_read(di, RK816_TS_ADC_REGL) << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) 	val |= rk816_bat_read(di, RK816_TS_ADC_REGH) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) 	res = ((di->voltage_k * val) / 1000 + di->voltage_b) * 1000 / 2200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) 	res = res * 1000 / di->pdata->ntc_factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) 	DBG("<%s>. val=%d, ntc_res=%d, factor=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) 	    __func__, val, res, di->pdata->ntc_factor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) 	DBG("<%s>. t=[%d'C(%d) ~ %dC(%d)]\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) 	    di->pdata->ntc_degree_from, di->pdata->ntc_table[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) 	    di->pdata->ntc_degree_from + di->pdata->ntc_size - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) 	    di->pdata->ntc_table[di->pdata->ntc_size - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) static int rk816_bat_temperature_chrg(struct rk816_battery *di, int temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) 	static int temp_triggered, config_index = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) 	int i, up_temp, down_temp, cfg_current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) 	u8 usb_ctrl, chrg_ctrl1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) 	int now_temp = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) 	int cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) 	for (i = 0; i < di->pdata->tc_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) 		up_temp = di->pdata->tc_table[i].temp_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) 		down_temp = di->pdata->tc_table[i].temp_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) 		cfg_current = di->pdata->tc_table[i].chrg_current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) 		if (now_temp >= down_temp && now_temp <= up_temp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) 			/* Temp range or charger are not update, return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) 			if (config_index == i && !di->charger_changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) 			config_index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) 			di->charger_changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) 			temp_triggered = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) 			if (di->pdata->tc_table[i].set_chrg_current) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) 				rk816_bat_set_chrg_current(di, cfg_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) 				if (!di->over_20mR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) 					cur =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) 					  RES_FAC_MUX(CHRG_CUR_SEL[cfg_current],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) 						      di->res_fac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) 					cur =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) 					  RES_FAC_DIV(CHRG_CUR_SEL[cfg_current],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) 						      di->res_fac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) 				BAT_INFO("temperature = %d'C[%d~%d'C], chrg current = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) 					 now_temp, down_temp, up_temp, cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) 				rk816_bat_set_input_current(di, cfg_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) 				BAT_INFO("temperature = %d'C[%d~%d'C], input current = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) 					 now_temp, down_temp, up_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) 					 CHRG_CUR_INPUT[cfg_current]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) 			return 0;	/* return after configure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) 	 * means: current temperature not covers above case, temperature rolls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) 	 * back to normal range, so restore default value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) 	if (temp_triggered) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) 		temp_triggered = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) 		config_index = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) 		rk816_bat_set_chrg_current(di, di->chrg_cur_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) 		if (di->ac_in || di->dc_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) 			rk816_bat_set_input_current(di, di->chrg_cur_input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) 			rk816_bat_set_input_current(di, INPUT_CUR450MA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) 		usb_ctrl = rk816_bat_read(di, RK816_USB_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) 		chrg_ctrl1 = rk816_bat_read(di, RK816_CHRG_CTRL_REG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) 		cfg_current = chrg_ctrl1 & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) 		if (!di->over_20mR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) 			cur =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) 			  RES_FAC_MUX(CHRG_CUR_SEL[cfg_current], di->res_fac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) 			cur =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) 			  RES_FAC_DIV(CHRG_CUR_SEL[cfg_current], di->res_fac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) 		BAT_INFO("roll back temp %d'C, current chrg = %d, input = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) 			 now_temp, cur, CHRG_CUR_INPUT[(usb_ctrl & 0x0f)]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) static void rk816_bat_update_temperature(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) 	u32 ntc_size, *ntc_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) 	int i, res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) 	ntc_table = di->pdata->ntc_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) 	ntc_size = di->pdata->ntc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) 	di->temperature = VIRTUAL_TEMPERATURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) 	if (ntc_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) 		res = rk816_bat_get_ntc_res(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) 		if (res < ntc_table[ntc_size - 1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) 			BAT_INFO("bat ntc upper max degree: R=%d\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) 			rk816_bat_set_input_current(di, INPUT_CUR80MA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) 		} else if (res > ntc_table[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) 			BAT_INFO("bat ntc lower min degree: R=%d\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) 			rk816_bat_set_input_current(di, INPUT_CUR80MA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) 			for (i = 0; i < ntc_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) 				if (res >= ntc_table[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) 			di->temperature = (i + di->pdata->ntc_degree_from) * 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) 			rk816_bat_temperature_chrg(di, di->temperature / 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) static void rk816_bat_update_ocv_table(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) 	static bool initialized;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) 	static int temp_idx, temperature_sum, last_avg_temp, curr_avg_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) 	static int temp_record_table[TEMP_RECORD_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) 	int i, curr_temp = di->temperature / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) 	if (di->pdata->temp_t_num < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) 	/* only run once for initialize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) 	if (!initialized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) 		for (i = 0; i < TEMP_RECORD_NUM; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) 			temp_record_table[i] = curr_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) 		temperature_sum = curr_temp * TEMP_RECORD_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) 		last_avg_temp = curr_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) 		initialized = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) 	/* pick out earliest temperature from sum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) 	temperature_sum -= temp_record_table[temp_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) 	/* add current temperature into sum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) 	temp_record_table[temp_idx] = curr_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) 	temperature_sum += curr_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) 	/* new avg temperature currently */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) 	curr_avg_temp = temperature_sum / TEMP_RECORD_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) 	/* move to next idx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) 	temp_idx = (temp_idx + 1) % TEMP_RECORD_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) 	DBG("<%s>: temp_idx=%d, curr_temp=%d, last_avg=%d, curr_avg=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) 	    __func__, temp_idx, curr_temp, last_avg_temp, curr_avg_temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) 	/* tempearture changed, update ocv table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) 	if (curr_avg_temp != last_avg_temp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) 		BAT_INFO("OCV table update, temperature now=%d, last=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) 			 curr_avg_temp, last_avg_temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) 		rk816_bat_setup_ocv_table(di, curr_avg_temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) 		last_avg_temp = curr_avg_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) 		if (!dbg_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) 		for (i = 0; i < di->pdata->ocv_size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) 			DBG("* ocv_table[%d]=%d\n", i, di->pdata->ocv_table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) static void rk816_battery_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) 	struct rk816_battery *di =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) 		container_of(work, struct rk816_battery, bat_delay_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) 	rk816_bat_update_info(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) 	rk816_bat_wait_finish_sig(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) 	rk816_bat_rsoc_daemon(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) 	rk816_bat_check_charger(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) 	rk816_bat_update_temperature(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) 	rk816_bat_update_ocv_table(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) 	rk816_bat_lowpwr_check(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) 	rk816_bat_display_smooth(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) 	rk816_bat_power_supply_changed(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) 	rk816_bat_save_data(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) 	rk816_bat_debug_info(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) 	queue_delayed_work(di->bat_monitor_wq, &di->bat_delay_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) 			   msecs_to_jiffies(di->monitor_ms));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) static void rk816_bat_discnt_evt_worker(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) 	struct rk816_battery *di = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) 			struct rk816_battery, discnt_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) 	if (extcon_get_state(di->cable_edev, EXTCON_USB) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) 		BAT_INFO("receive extcon notifier event: DISCNT...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) 		rk816_bat_set_chrg_param(di, USB_TYPE_NONE_CHARGER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) static void rk816_bat_host_evt_worker(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) 	struct rk816_battery *di = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) 			struct rk816_battery, host_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) 	struct extcon_dev *edev = di->cable_edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) 	/* Determine charger type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) 	if (extcon_get_state(edev, EXTCON_USB_VBUS_EN) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) 		rk816_bat_set_otg_in(di, ONLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) 		BAT_INFO("receive extcon notifier event: OTG ON...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) 		if (di->dc_in && di->pdata->power_dc2otg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) 			BAT_INFO("otg power from dc adapter\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) 			rk816_bat_set_otg_power(di, USB_OTG_POWER_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) 	} else if (extcon_get_state(edev, EXTCON_USB_VBUS_EN) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) 		BAT_INFO("receive extcon notifier event: OTG OFF...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) 		rk816_bat_set_otg_in(di, OFFLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) 		rk816_bat_set_otg_power(di, USB_OTG_POWER_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) static void rk816_bat_charger_evt_worker(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) 	struct rk816_battery *di = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) 				struct rk816_battery, usb_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) 	struct extcon_dev *edev = di->cable_edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) 	enum charger_t charger = USB_TYPE_UNKNOWN_CHARGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) 	static const char *event[] = {"UN", "NONE", "USB", "AC", "CDP1.5A"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) 	/* Determine charger type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) 	if (extcon_get_state(edev, EXTCON_CHG_USB_SDP) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) 		charger = USB_TYPE_USB_CHARGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) 	else if (extcon_get_state(edev, EXTCON_CHG_USB_DCP) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) 		charger = USB_TYPE_AC_CHARGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) 	else if (extcon_get_state(edev, EXTCON_CHG_USB_CDP) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) 		charger = USB_TYPE_CDP_CHARGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) 		charger = USB_TYPE_NONE_CHARGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) 	if (charger != USB_TYPE_UNKNOWN_CHARGER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) 		BAT_INFO("receive extcon notifier event: %s...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) 			 event[charger]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) 		rk816_bat_set_chrg_param(di, charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) static int rk816_bat_charger_evt_notifier(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) 					  unsigned long event, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) 	struct rk816_battery *di =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) 		container_of(nb, struct rk816_battery, cable_cg_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) 	queue_delayed_work(di->usb_charger_wq, &di->usb_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) 			   msecs_to_jiffies(10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) 	return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) static int rk816_bat_discnt_evt_notfier(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) 					unsigned long event, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) 	struct rk816_battery *di =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) 		container_of(nb, struct rk816_battery, cable_discnt_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) 	queue_delayed_work(di->usb_charger_wq, &di->discnt_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) 			   msecs_to_jiffies(10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) 	return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) static int rk816_bat_host_evt_notifier(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) 				       unsigned long event, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) 	struct rk816_battery *di =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) 		container_of(nb, struct rk816_battery, cable_host_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) 	queue_delayed_work(di->usb_charger_wq, &di->host_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) 			   msecs_to_jiffies(10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) 	return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) static irqreturn_t rk816_vb_low_irq(int irq, void *bat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) 	struct rk816_battery *di = (struct rk816_battery *)bat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) 	BAT_INFO("lower power yet, power off system! v=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) 		 di->voltage_avg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) 	di->dsoc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) 	rk_send_wakeup_key();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) 	power_supply_changed(di->bat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) static irqreturn_t rk816_plug_in(int irq, void *bat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) 	rk_send_wakeup_key();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) 	BAT_INFO("pmic: plug in\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) static irqreturn_t rk816_cvtlmt(int irq, void  *bat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) 	struct rk816_battery *di = (struct rk816_battery *)bat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) 	di->cvtlmt_int_event = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) 	BAT_INFO("pmic: cvtlmt irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) static irqreturn_t rk816_plug_out(int irq, void  *bat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) 	rk_send_wakeup_key();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) 	BAT_INFO("pmic: plug out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) static irqreturn_t rk816_vbat_dc_det(int irq, void *bat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) 	struct rk816_battery *di = (struct rk816_battery *)bat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) 	if (gpio_get_value(di->pdata->dc_det_pin))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) 		irq_set_irq_type(irq, IRQF_TRIGGER_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) 		irq_set_irq_type(irq, IRQF_TRIGGER_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) 	BAT_INFO("dc det in/out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) 	queue_delayed_work(di->usb_charger_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) 			   &di->dc_delay_work, msecs_to_jiffies(500));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) 	rk_send_wakeup_key();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) static void rk816_bat_init_sysfs(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) 	for (i = 0; i < ARRAY_SIZE(rk816_bat_attr); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) 		ret = sysfs_create_file(&di->dev->kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) 					&rk816_bat_attr[i].attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) 			dev_err(di->dev, "create bat node(%s) error\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) 				rk816_bat_attr[i].attr.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) static int rk816_bat_init_irqs(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) 	int plug_in_irq, plug_out_irq, vb_lo_irq, cvtlmt_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) 	struct rk808 *rk816 = di->rk816;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) 	struct platform_device *pdev = di->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) 	vb_lo_irq = regmap_irq_get_virq(rk816->irq_data, RK816_IRQ_VB_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) 	if (vb_lo_irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) 		dev_err(&pdev->dev, "find vb_lo_irq error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) 		return vb_lo_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) 	plug_in_irq = regmap_irq_get_virq(rk816->battery_irq_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) 					  RK816_IRQ_PLUG_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) 	if (plug_in_irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) 		dev_err(&pdev->dev, "find plug_in_irq error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) 		return plug_in_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) 	plug_out_irq = regmap_irq_get_virq(rk816->battery_irq_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) 					   RK816_IRQ_PLUG_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) 	if (plug_out_irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) 		dev_err(&pdev->dev, "find plug_out_irq error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) 		return plug_out_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) 	cvtlmt_irq = regmap_irq_get_virq(rk816->battery_irq_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) 					 RK816_IRQ_CHG_CVTLIM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) 	if (cvtlmt_irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) 		dev_err(&pdev->dev, "find cvtlmt_irq error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) 		return cvtlmt_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) 	/* low power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) 	ret = devm_request_threaded_irq(di->dev, vb_lo_irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) 					rk816_vb_low_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) 					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) 					"rk816_vb_low", di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) 		dev_err(di->dev, "vb low irq request failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) 	enable_irq_wake(vb_lo_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) 	/* plug in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) 	ret = devm_request_threaded_irq(di->dev, plug_in_irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) 					rk816_plug_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) 					IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) 					"rk816_plug_in", di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) 		dev_err(di->dev, "plug in irq request failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) 	/* plug out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) 	ret = devm_request_threaded_irq(di->dev, plug_out_irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) 					rk816_plug_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) 					IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) 					"rk816_plug_out", di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) 		dev_err(di->dev, "plug out irq request failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) 	/* cvtlmt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) 	ret = devm_request_threaded_irq(di->dev, cvtlmt_irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) 					rk816_cvtlmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) 					IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) 					"rk816_cvtlmt", di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) 		dev_err(di->dev, "cvtlmt irq request failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) 	disable_irq(cvtlmt_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) 	di->cvtlmt_irq = cvtlmt_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) static void rk816_bat_init_info(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) 	di->design_cap = di->pdata->design_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) 	di->qmax = di->pdata->design_qmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) 	di->bat_res = di->pdata->bat_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) 	di->sleep_chrg_status = rk816_bat_get_chrg_status(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) 	di->monitor_ms = di->pdata->monitor_sec * TIMER_MS_COUNTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) 	di->prop_status = POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) 	di->boot_base = POWER_ON_SEC_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) 	di->chrg_finish_base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) 	di->plug_in_base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) 	di->plug_out_base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) static enum charger_t rk816_bat_init_adc_dc_det(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) 	return rk816_bat_get_adc_dc_state(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) static enum charger_t rk816_bat_init_gpio_dc_det(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) 	int ret, level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) 	unsigned long irq_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) 	unsigned int dc_det_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) 	enum charger_t type = DC_TYPE_NONE_CHARGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) 	if (gpio_is_valid(di->pdata->dc_det_pin)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) 		ret = devm_gpio_request(di->dev, di->pdata->dc_det_pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) 					"rk816_dc_det");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) 			dev_err(di->dev, "Failed to request gpio %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) 				di->pdata->dc_det_pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) 		ret = gpio_direction_input(di->pdata->dc_det_pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) 			dev_err(di->dev, "failed to set gpio input\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) 		level = gpio_get_value(di->pdata->dc_det_pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) 		if (level == di->pdata->dc_det_level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) 			type = DC_TYPE_DC_CHARGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) 			type = DC_TYPE_NONE_CHARGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) 		if (level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) 			irq_flags = IRQF_TRIGGER_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) 			irq_flags = IRQF_TRIGGER_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) 		dc_det_irq = gpio_to_irq(di->pdata->dc_det_pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) 		ret = devm_request_irq(di->dev, dc_det_irq, rk816_vbat_dc_det,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) 				       irq_flags, "rk816_dc_det", di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) 		if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) 			dev_err(di->dev, "rk816_dc_det_irq request failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) 		enable_irq_wake(dc_det_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) 	return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) static enum charger_t rk816_bat_init_dc_det(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) 	enum charger_t type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) 	if (di->pdata->dc_det_adc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) 		type = rk816_bat_init_adc_dc_det(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) 		type = rk816_bat_init_gpio_dc_det(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) 	return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) static int rk816_bat_init_charger(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) 	enum charger_t dc_charger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) 	struct device *dev = di->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) 	struct extcon_dev *edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) 	di->usb_charger_wq = alloc_ordered_workqueue("%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) 				WQ_MEM_RECLAIM | WQ_FREEZABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) 				"rk816-bat-charger-wq");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) 	INIT_DELAYED_WORK(&di->dc_delay_work, rk816_bat_dc_delay_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) 	/* Find extcon phandle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) 	edev = extcon_get_edev_by_phandle(dev->parent, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) 	if (IS_ERR(edev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) 		if (PTR_ERR(edev) != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) 			dev_err(dev, "Invalid or missing extcon\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) 		return PTR_ERR(edev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) 	/* Register chargers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) 	INIT_DELAYED_WORK(&di->usb_work, rk816_bat_charger_evt_worker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) 	di->cable_cg_nb.notifier_call = rk816_bat_charger_evt_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) 	ret = extcon_register_notifier(edev, EXTCON_CHG_USB_SDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) 				       &di->cable_cg_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) 		dev_err(dev, "failed to register notifier for SDP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) 	ret = extcon_register_notifier(edev, EXTCON_CHG_USB_DCP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) 				       &di->cable_cg_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) 		dev_err(dev, "failed to register notifier for DCP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) 		extcon_unregister_notifier(edev, EXTCON_CHG_USB_SDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) 					   &di->cable_cg_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) 	ret = extcon_register_notifier(edev, EXTCON_CHG_USB_CDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) 				       &di->cable_cg_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) 		dev_err(dev, "failed to register notifier for CDP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) 		extcon_unregister_notifier(edev, EXTCON_CHG_USB_SDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) 					   &di->cable_cg_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) 		extcon_unregister_notifier(edev, EXTCON_CHG_USB_DCP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) 					   &di->cable_cg_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) 	/* Register host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) 	INIT_DELAYED_WORK(&di->host_work, rk816_bat_host_evt_worker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) 	di->cable_host_nb.notifier_call = rk816_bat_host_evt_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) 	ret = extcon_register_notifier(edev, EXTCON_USB_VBUS_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) 				       &di->cable_host_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) 		dev_err(dev, "failed to register notifier for HOST\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) 		extcon_unregister_notifier(edev, EXTCON_CHG_USB_SDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) 					   &di->cable_cg_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) 		extcon_unregister_notifier(edev, EXTCON_CHG_USB_DCP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) 					   &di->cable_cg_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) 		extcon_unregister_notifier(edev, EXTCON_CHG_USB_CDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) 					   &di->cable_cg_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) 	/* Register discnt usb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) 	INIT_DELAYED_WORK(&di->discnt_work, rk816_bat_discnt_evt_worker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) 	di->cable_discnt_nb.notifier_call = rk816_bat_discnt_evt_notfier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) 	ret = extcon_register_notifier(edev, EXTCON_USB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) 				       &di->cable_discnt_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) 		dev_err(dev, "failed to register notifier for HOST\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) 		extcon_unregister_notifier(edev, EXTCON_CHG_USB_SDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) 					   &di->cable_cg_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) 		extcon_unregister_notifier(edev, EXTCON_CHG_USB_DCP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) 					   &di->cable_cg_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) 		extcon_unregister_notifier(edev, EXTCON_CHG_USB_CDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) 					   &di->cable_cg_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) 		extcon_unregister_notifier(edev, EXTCON_USB_VBUS_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) 					   &di->cable_host_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) 	di->cable_edev = edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) 	/* Check usb and otg state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) 	schedule_delayed_work(&di->host_work, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) 	schedule_delayed_work(&di->usb_work, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) 	BAT_INFO("register extcon evt notifier\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) 	/* adc dc need poll every 1s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) 	if (di->pdata->dc_det_adc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) 		queue_delayed_work(di->usb_charger_wq, &di->dc_delay_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) 				   msecs_to_jiffies(1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) 	dc_charger = rk816_bat_init_dc_det(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) 	rk816_bat_set_chrg_param(di, dc_charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) 	if (di->dc_in && di->otg_in && di->pdata->power_dc2otg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) 		BAT_INFO("otg power from dc adapter\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) 		rk816_bat_set_otg_power(di, USB_OTG_POWER_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) static time64_t rk816_get_rtc_sec(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) 	struct rtc_time tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) 	struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) 	err = rtc_read_time(rtc, &tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) 		dev_err(rtc->dev.parent, "read hardware clk failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) 	err = rtc_valid_tm(&tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) 		dev_err(rtc->dev.parent, "invalid date time\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) 	return rtc_tm_to_time64(&tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) static int rk816_bat_rtc_sleep_sec(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) 	int interval_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) 	interval_sec = rk816_get_rtc_sec() - di->rtc_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) 	return (interval_sec > 0) ? interval_sec : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) static void rk816_bat_init_ts_detect(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) 	u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) 	if (!di->pdata->ntc_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) 	/* Pin func: ts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) 	buf = rk816_bat_read(di, RK816_GPIO_IO_POL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) 	buf &= ~BIT(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) 	rk816_bat_write(di, RK816_GPIO_IO_POL_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) 	/* External temperature monitoring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) 	buf = rk816_bat_read(di, RK816_TS_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) 	buf &= ~BIT(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) 	rk816_bat_write(di, RK816_TS_CTRL_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) 	/* select ua */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) 	buf = rk816_bat_read(di, RK816_TS_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) 	buf &= ~ADC_CUR_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) 	if (di->pdata->ntc_factor == NTC_CALC_FACTOR_80UA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) 		buf |= ADC_CUR_80UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) 	else if (di->pdata->ntc_factor == NTC_CALC_FACTOR_60UA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) 		buf |= ADC_CUR_60UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) 	else if (di->pdata->ntc_factor == NTC_CALC_FACTOR_40UA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) 		buf |= ADC_CUR_40UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) 		buf |= ADC_CUR_20UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) 	rk816_bat_write(di, RK816_TS_CTRL_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) 	/* ADC_TS_EN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) 	buf = rk816_bat_read(di, RK816_ADC_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) 	buf |= BIT(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) 	rk816_bat_write(di, RK816_ADC_CTRL_REG, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) static void rk816_bat_init_fg(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) 	rk816_bat_enable_input_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) 	rk816_bat_enable_gauge(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) 	rk816_bat_init_voltage_kb(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) 	rk816_bat_init_poffset(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) 	rk816_bat_select_sample_res(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) 	rk816_bat_set_relax_sample(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) 	rk816_bat_set_ioffset_sample(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) 	rk816_bat_set_ocv_sample(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) 	rk816_bat_init_ts_detect(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) 	rk816_bat_update_temperature(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) 	rk816_bat_setup_ocv_table(di, di->temperature / 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) 	rk816_bat_init_rsoc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) 	rk816_bat_init_coulomb_cap(di, di->nac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) 	rk816_bat_init_age_algorithm(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) 	rk816_bat_init_chrg_config(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) 	rk816_bat_init_zero_table(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) 	rk816_bat_init_caltimer(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) 	rk816_bat_init_dsoc_algorithm(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) 	di->voltage_avg = rk816_bat_get_avg_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) 	di->voltage_ocv = rk816_bat_get_ocv_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) 	di->voltage_relax = rk816_bat_get_relax_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) 	di->current_avg = rk816_bat_get_avg_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) 	di->current_relax = rk816_bat_get_relax_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) 	di->remain_cap = rk816_bat_get_coulomb_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) 	di->dbg_pwr_dsoc = di->dsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) 	di->dbg_pwr_rsoc = di->rsoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) 	di->dbg_pwr_vol = di->voltage_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) 	rk816_bat_dump_regs(di, 0x99, 0xee);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) 	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 4452) 	    di->nac, di->remain_cap, di->voltage_ocv, di->voltage_avg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) 	    di->voltage_relax, di->dsoc, di->rsoc, di->current_avg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) static int rk816_bat_read_ocv_tables(struct rk816_battery *di,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) 				     struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) 	struct battery_platform_data *pdata = di->pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) 	u32 negative, value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) 	int length, i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) 	int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) 	/* t0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) 	if (of_find_property(np, "table_t0", &length) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) 	    of_find_property(np, "temp_t0", &length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) 		DBG("%s: read table_t0\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) 		if (of_property_read_u32_array(np, "table_t0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) 					       pdata->table_t[idx],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) 					       pdata->ocv_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) 			dev_err(di->dev, "invalid table_t0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) 		if (of_property_read_u32_index(np, "temp_t0", 1, &value) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) 		    of_property_read_u32_index(np, "temp_t0", 0, &negative)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) 			dev_err(di->dev, "invalid temp_t0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) 		if (negative)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) 			pdata->temp_t[idx] = -value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) 			pdata->temp_t[idx] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) 		idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) 	/* t1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) 	if (of_find_property(np, "table_t1", &length) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) 	    of_find_property(np, "temp_t1", &length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) 		DBG("%s: read table_t1\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) 		if (of_property_read_u32_array(np, "table_t1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) 					       pdata->table_t[idx],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) 					       pdata->ocv_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) 			dev_err(di->dev, "invalid table_t1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) 		if (of_property_read_u32_index(np, "temp_t1", 1, &value) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) 		    of_property_read_u32_index(np, "temp_t1", 0, &negative)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) 			dev_err(di->dev, "invalid temp_t1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) 		if (negative)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) 			pdata->temp_t[idx] = -value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) 			pdata->temp_t[idx] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) 		idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) 	/* t2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) 	if (of_find_property(np, "table_t2", &length) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) 	    of_find_property(np, "temp_t2", &length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) 		DBG("%s: read table_t2\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) 		if (of_property_read_u32_array(np, "table_t2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) 					       pdata->table_t[idx],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) 					       pdata->ocv_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) 			dev_err(di->dev, "invalid table_t2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) 		if (of_property_read_u32_index(np, "temp_t2", 1, &value) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) 		    of_property_read_u32_index(np, "temp_t2", 0, &negative)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) 			dev_err(di->dev, "invalid temp_t2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) 		if (negative)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) 			pdata->temp_t[idx] = -value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) 			pdata->temp_t[idx] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) 		idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) 	/* t3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) 	if (of_find_property(np, "table_t3", &length) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) 	    of_find_property(np, "temp_t3", &length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) 		DBG("%s: read table_t3\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) 		if (of_property_read_u32_array(np, "table_t3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) 					       pdata->table_t[idx],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) 					       pdata->ocv_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) 			dev_err(di->dev, "invalid table_t3\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) 		if (of_property_read_u32_index(np, "temp_t3", 1, &value) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) 		    of_property_read_u32_index(np, "temp_t3", 0, &negative)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) 			dev_err(di->dev, "invalid temp_t3\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) 		if (negative)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) 			pdata->temp_t[idx] = -value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) 			pdata->temp_t[idx] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) 		idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) 	di->pdata->temp_t_num = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) 	DBG("realtime ocv table nums=%d\n", di->pdata->temp_t_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) 	if (dbg_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) 		for (j = 0; j < pdata->temp_t_num; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) 			DBG("\n\ntemperature[%d]=%d\n", j, pdata->temp_t[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) 			for (i = 0; i < di->pdata->ocv_size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) 				DBG("table_t%d[%d]=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) 				    j, i, pdata->table_t[j][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) static int parse_temperature_chrg_table(struct rk816_battery *di,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) 					struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) 	int size, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) 	int i, chrg_current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) 	const __be32 *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) 	if (!of_find_property(np, "temperature_chrg_table_v2", &size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) 	list = of_get_property(np, "temperature_chrg_table_v2", &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) 	size /= sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) 	if (!size || (size % 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) 		dev_err(di->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) 			"invalid temperature_chrg_table: size=%d\n", size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) 	count = size / 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) 	di->pdata->tc_count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) 	di->pdata->tc_table = devm_kzalloc(di->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) 					   count * sizeof(*di->pdata->tc_table),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) 					   GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) 	if (!di->pdata->tc_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) 	for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) 		/* temperature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) 		di->pdata->tc_table[i].temp_down = be32_to_cpu(*list++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) 		di->pdata->tc_table[i].temp_up = be32_to_cpu(*list++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) 		 * because charge current lowest level is 1000mA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) 		 * higher than or equal 1000ma, select charge current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) 		 * lower than 1000ma, must select input current.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) 		chrg_current = be32_to_cpu(*list++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) 		if (chrg_current >= 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) 			di->pdata->tc_table[i].set_chrg_current = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) 			di->pdata->tc_table[i].chrg_current =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) 				rk816_bat_decode_chrg_current(di, chrg_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) 			di->pdata->tc_table[i].chrg_current =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) 				rk816_bat_decode_input_current(di, chrg_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) 		DBG("temp%d: [%d, %d], chrg_current=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) 		    i, di->pdata->tc_table[i].temp_down,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) 		    di->pdata->tc_table[i].temp_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) 		    di->pdata->tc_table[i].chrg_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) static int rk816_bat_parse_dt(struct rk816_battery *di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) 	u32 out_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) 	int length, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) 	size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) 	struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) 	struct battery_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) 	struct device *dev = di->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) 	enum of_gpio_flags flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) 	np = of_find_node_by_name(di->rk816->i2c->dev.of_node, "battery");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) 	if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) 		dev_err(dev, "battery node not found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) 	pdata = devm_kzalloc(di->dev, sizeof(*pdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) 	if (!pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) 	di->pdata = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) 	/* init default param */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) 	pdata->bat_res = DEFAULT_BAT_RES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) 	pdata->monitor_sec = DEFAULT_MONITOR_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) 	pdata->pwroff_vol = DEFAULT_PWROFF_VOL_THRESD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) 	pdata->sleep_exit_current = DEFAULT_SLP_EXIT_CUR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) 	pdata->sleep_enter_current = DEFAULT_SLP_ENTER_CUR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) 	pdata->sleep_filter_current = DEFAULT_SLP_FILTER_CUR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) 	pdata->bat_mode = MODE_BATTARY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) 	pdata->max_soc_offset = DEFAULT_MAX_SOC_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) 	pdata->fb_temp = DEFAULT_FB_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) 	pdata->energy_mode = DEFAULT_ENERGY_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) 	pdata->zero_reserve_dsoc = DEFAULT_ZERO_RESERVE_DSOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) 	pdata->sample_res = DEFAULT_SAMPLE_RES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) 	/* parse necessary param */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) 	if (!of_find_property(np, "ocv_table", &length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) 		dev_err(dev, "ocv_table not found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) 	pdata->ocv_size = length / sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) 	if (pdata->ocv_size <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) 		dev_err(dev, "invalid ocv table\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) 	size = sizeof(*pdata->ocv_table) * pdata->ocv_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) 	pdata->ocv_table = devm_kzalloc(di->dev, size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) 	if (!pdata->ocv_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) 	ret = of_property_read_u32_array(np, "ocv_table", pdata->ocv_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) 					 pdata->ocv_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) 	ret = rk816_bat_read_ocv_tables(di, np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) 		di->pdata->temp_t_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) 		dev_err(dev, "read table_t error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) 	ret = of_property_read_u32(np, "design_capacity", &out_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) 		dev_err(dev, "design_capacity not found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) 	pdata->design_capacity = out_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) 	ret = of_property_read_u32(np, "design_qmax", &out_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) 		dev_err(dev, "design_qmax not found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) 	pdata->design_qmax = out_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) 	ret = of_property_read_u32(np, "max_chrg_current", &out_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) 		dev_err(dev, "max_chrg_current missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) 	pdata->max_chrg_current = out_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) 	ret = of_property_read_u32(np, "max_input_current", &out_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) 		dev_err(dev, "max_input_current missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) 	pdata->max_input_current = out_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) 	ret = of_property_read_u32(np, "max_chrg_voltage", &out_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) 		dev_err(dev, "max_chrg_voltage missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) 	pdata->max_chrg_voltage = out_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) 	if (out_value >= 4300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) 		pdata->zero_algorithm_vol = DEFAULT_ALGR_VOL_THRESD2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) 		pdata->zero_algorithm_vol = DEFAULT_ALGR_VOL_THRESD1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) 	pdata->extcon = device_property_read_bool(dev->parent, "extcon");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) 	if (!pdata->extcon) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) 		dev_err(dev, "Can't find extcon node under rk816 node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) 	/* parse unnecessary param */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) 	of_property_read_u32(np, "sample_res", &pdata->sample_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) 	ret = of_property_read_u32(np, "fb_temperature", &pdata->fb_temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) 		dev_err(dev, "fb_temperature missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) 	ret = of_property_read_u32(np, "energy_mode", &pdata->energy_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) 		dev_err(dev, "energy_mode missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) 	ret = of_property_read_u32(np, "max_soc_offset",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) 				   &pdata->max_soc_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) 		dev_err(dev, "max_soc_offset missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) 	ret = of_property_read_u32(np, "monitor_sec", &pdata->monitor_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) 		dev_err(dev, "monitor_sec missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) 	ret = of_property_read_u32(np, "zero_algorithm_vol",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) 				   &pdata->zero_algorithm_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) 		dev_err(dev, "zero_algorithm_vol missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) 	ret = of_property_read_u32(np, "zero_reserve_dsoc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) 				   &pdata->zero_reserve_dsoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) 	ret = of_property_read_u32(np, "virtual_power", &pdata->bat_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) 		dev_err(dev, "virtual_power missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) 	ret = of_property_read_u32(np, "power_dc2otg", &pdata->power_dc2otg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) 		dev_err(dev, "power_dc2otg missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) 	ret = of_property_read_u32(np, "bat_res", &pdata->bat_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) 		dev_err(dev, "bat_res missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) 	ret = of_property_read_u32(np, "sleep_enter_current",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) 				   &pdata->sleep_enter_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) 		dev_err(dev, "sleep_enter_current missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) 	ret = of_property_read_u32(np, "sleep_exit_current",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) 				   &pdata->sleep_exit_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) 		dev_err(dev, "sleep_exit_current missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) 	ret = of_property_read_u32(np, "sleep_filter_current",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) 				   &pdata->sleep_filter_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) 		dev_err(dev, "sleep_filter_current missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) 	ret = of_property_read_u32(np, "power_off_thresd", &pdata->pwroff_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) 		dev_err(dev, "power_off_thresd missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) 	ret = of_property_read_u32(np, "otg5v_suspend_enable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) 				   &pdata->otg5v_suspend_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) 		pdata->otg5v_suspend_enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) 	if (!of_find_property(np, "dc_det_gpio", &length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) 		pdata->dc_det_pin = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) 		of_property_read_u32(np, "dc_det_adc", &pdata->dc_det_adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) 		if (!pdata->dc_det_adc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) 			BAT_INFO("not support dc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) 			BAT_INFO("support adc dc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) 		BAT_INFO("support gpio dc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) 		pdata->dc_det_pin = of_get_named_gpio_flags(np, "dc_det_gpio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) 							    0, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) 		if (gpio_is_valid(pdata->dc_det_pin)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) 			pdata->dc_det_level =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) 					(flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) 			/* if support dc, default set power_dc2otg = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) 			pdata->power_dc2otg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) 	if (!of_find_property(np, "ntc_table", &length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) 		pdata->ntc_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) 		/* get ntc degree base value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) 		ret = of_property_read_s32(np, "ntc_degree_from_v2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) 					   &pdata->ntc_degree_from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) 			dev_err(dev, "invalid ntc_degree_from_v2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) 		pdata->ntc_size = length / sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) 	if (pdata->ntc_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) 		size = sizeof(*pdata->ntc_table) * pdata->ntc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) 		pdata->ntc_table = devm_kzalloc(di->dev, size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) 		if (!pdata->ntc_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) 		ret = of_property_read_u32_array(np, "ntc_table",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) 						 pdata->ntc_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) 						 pdata->ntc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) 		if (pdata->ntc_table[0] < NTC_80UA_MAX_MEASURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) 			pdata->ntc_factor = NTC_CALC_FACTOR_80UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) 		else if (pdata->ntc_table[0] < NTC_60UA_MAX_MEASURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) 			pdata->ntc_factor = NTC_CALC_FACTOR_60UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) 		else if (pdata->ntc_table[0] < NTC_40UA_MAX_MEASURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) 			pdata->ntc_factor = NTC_CALC_FACTOR_40UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) 			pdata->ntc_factor = NTC_CALC_FACTOR_20UA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) 	ret = parse_temperature_chrg_table(di, np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) 	DBG("the battery dts info dump:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) 	    "bat_res:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) 	    "res_sample:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) 	    "max_input_currentmA:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) 	    "max_chrg_current:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) 	    "max_chrg_voltage:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) 	    "design_capacity:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) 	    "design_qmax :%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) 	    "sleep_enter_current:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) 	    "sleep_exit_current:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) 	    "sleep_filter_current:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) 	    "zero_algorithm_vol:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) 	    "zero_reserve_dsoc:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) 	    "monitor_sec:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) 	    "power_dc2otg:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) 	    "max_soc_offset:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) 	    "virtual_power:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) 	    "pwroff_vol:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) 	    "dc_det_adc:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) 	    "ntc_factor:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) 	    "ntc_size=%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) 	    "ntc_degree_from_v2:%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) 	    "ntc_degree_to:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) 	    pdata->bat_res, pdata->sample_res, pdata->max_input_current,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) 	    pdata->max_chrg_current, pdata->max_chrg_voltage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) 	    pdata->design_capacity, pdata->design_qmax,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) 	    pdata->sleep_enter_current, pdata->sleep_exit_current,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) 	    pdata->sleep_filter_current, pdata->zero_algorithm_vol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) 	    pdata->zero_reserve_dsoc, pdata->monitor_sec, pdata->power_dc2otg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) 	    pdata->max_soc_offset, pdata->bat_mode, pdata->pwroff_vol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) 	    pdata->dc_det_adc, pdata->ntc_factor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) 	    pdata->ntc_size, pdata->ntc_degree_from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) 	    pdata->ntc_degree_from + pdata->ntc_size - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) 	    );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) static const struct of_device_id rk816_battery_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) 	{.compatible = "rk816-battery",},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) static int rk816_battery_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) 	const struct of_device_id *of_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) 			of_match_device(rk816_battery_of_match, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) 	struct rk816_battery *di;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) 	struct rk808 *rk816 = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) 	if (!of_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) 		dev_err(&pdev->dev, "Failed to find matching dt id\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) 	di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) 	if (!di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) 	di->rk816 = rk816;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) 	di->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) 	di->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) 	di->regmap = rk816->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) 	platform_set_drvdata(pdev, di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) 	ret = rk816_bat_parse_dt(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) 		dev_err(&pdev->dev, "rk816 battery parse dt failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) 	if (!is_rk816_bat_exist(di)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) 		di->pdata->bat_mode = MODE_VIRTUAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) 		dev_err(&pdev->dev, "no battery, virtual power mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) 	ret = rk816_bat_init_power_supply(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) 		dev_err(&pdev->dev, "rk816 power supply register failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) 	rk816_bat_init_info(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) 	rk816_bat_init_fg(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) 	rk816_bat_init_leds(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) 	rk816_bat_init_charger(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) 	rk816_bat_init_sysfs(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) 	rk816_bat_register_fb_notify(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) 	wake_lock_init(&di->wake_lock, WAKE_LOCK_SUSPEND, "rk816_bat_lock");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) 	di->bat_monitor_wq = alloc_ordered_workqueue("%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) 			WQ_MEM_RECLAIM | WQ_FREEZABLE, "rk816-bat-monitor-wq");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) 	INIT_DELAYED_WORK(&di->bat_delay_work, rk816_battery_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) 	ret = rk816_bat_init_irqs(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) 		dev_err(&pdev->dev, "rk816 bat irq init failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) 		goto irq_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) 	queue_delayed_work(di->bat_monitor_wq, &di->bat_delay_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) 			   msecs_to_jiffies(TIMER_MS_COUNTS * 5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) 	BAT_INFO("driver version %s\n", DRIVER_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) irq_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972) 	cancel_delayed_work(&di->dc_delay_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) 	cancel_delayed_work(&di->bat_delay_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) 	cancel_delayed_work(&di->calib_delay_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) 	destroy_workqueue(di->bat_monitor_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) 	destroy_workqueue(di->usb_charger_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) 	rk816_bat_unregister_fb_notify(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) 	del_timer(&di->caltimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) 	wake_lock_destroy(&di->wake_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) static int rk816_battery_suspend(struct platform_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) 				 pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) 	struct rk816_battery *di = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) 	u8 st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) 	cancel_delayed_work_sync(&di->bat_delay_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) 	di->s2r = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) 	di->sleep_chrg_online = rk816_bat_chrg_online(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) 	di->sleep_chrg_status = rk816_bat_get_chrg_status(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) 	di->current_avg = rk816_bat_get_avg_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) 	di->remain_cap = rk816_bat_get_coulomb_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) 	di->rsoc = rk816_bat_get_rsoc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) 	di->rtc_base = rk816_get_rtc_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) 	rk816_bat_save_data(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) 	st = (rk816_bat_read(di, RK816_SUP_STS_REG) & CHRG_STATUS_MSK) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) 	di->slp_dcdc_en_reg = rk816_bat_read(di, RK816_SLP_DCDC_EN_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) 	/* enable sleep boost5v and otg5v */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) 	if (di->pdata->otg5v_suspend_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) 		if ((di->otg_in && !di->dc_in) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) 		    (di->otg_in && di->dc_in && !di->pdata->power_dc2otg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) 			rk816_bat_set_bits(di, RK816_SLP_DCDC_EN_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) 					   OTG_BOOST_SLP_ON, OTG_BOOST_SLP_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) 			BAT_INFO("suspend: otg 5v on\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) 			/* disable sleep otg5v */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) 			rk816_bat_set_bits(di, RK816_SLP_DCDC_EN_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) 					   OTG_BOOST_SLP_ON, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) 			BAT_INFO("suspend: otg 5v off\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) 		/* disable sleep otg5v */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) 		rk816_bat_set_bits(di, RK816_SLP_DCDC_EN_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) 				   OTG_BOOST_SLP_ON, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) 		BAT_INFO("suspend: otg 5v off\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) 	/* if not CHARGE_FINISH, reinit chrg_finish_base.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) 	 * avoid sleep loop in suspend and resume all the time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) 	if (di->sleep_chrg_status != CHARGE_FINISH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) 		di->chrg_finish_base = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) 	/* avoid: enter suspend from MODE_ZERO: load from heavy to light */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) 	if ((di->work_mode == MODE_ZERO) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) 	    (di->sleep_chrg_online) && (di->current_avg >= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) 		DBG("suspend: MODE_ZERO exit...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) 		/* it need't do prepare for mode finish and smooth, it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) 		 * be done in display_smooth
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) 		if (di->sleep_chrg_status == CHARGE_FINISH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) 			di->work_mode = MODE_FINISH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) 			di->chrg_finish_base = get_boot_sec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) 			di->work_mode = MODE_SMOOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) 			rk816_bat_smooth_algo_prepare(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) 	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 5045) 		 di->dsoc, di->rsoc, di->current_avg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) 		 rk816_bat_get_avg_voltage(di), rk816_bat_get_coulomb_cap(di),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) 		 di->sleep_dischrg_sec, di->sleep_chrg_online, bat_status[st]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) static int rk816_battery_resume(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) 	int interval_sec, pwroff_vol, time_step = DISCHRG_TIME_STEP1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) 	struct rk816_battery *di = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) 	u8 st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) 	di->s2r = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) 	di->voltage_avg = rk816_bat_get_avg_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) 	di->current_avg = rk816_bat_get_avg_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) 	di->voltage_relax = rk816_bat_get_relax_voltage(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) 	di->current_relax = rk816_bat_get_relax_current(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) 	di->remain_cap = rk816_bat_get_coulomb_cap(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) 	di->rsoc = rk816_bat_get_rsoc(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) 	interval_sec = rk816_bat_rtc_sleep_sec(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) 	di->sleep_sum_sec += interval_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) 	pwroff_vol = di->pdata->pwroff_vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) 	st = (rk816_bat_read(di, RK816_SUP_STS_REG) & CHRG_STATUS_MSK) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) 	/* resume sleep boost5v and otg5v */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) 	rk816_bat_set_bits(di, RK816_SLP_DCDC_EN_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) 			   OTG_BOOST_SLP_ON, di->slp_dcdc_en_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) 	if (!di->sleep_chrg_online) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) 		/* only add up discharge sleep seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) 		di->sleep_dischrg_sec += interval_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) 		if (di->voltage_avg <= pwroff_vol + 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) 			time_step = DISCHRG_TIME_STEP1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) 			time_step = DISCHRG_TIME_STEP2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) 	BAT_INFO("resume: dl=%d rl=%d c=%d v=%d rv=%d cap=%d dt=%d at=%ld ch=%d st=%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083) 		 di->dsoc, di->rsoc, di->current_avg, di->voltage_avg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) 		 di->voltage_relax, rk816_bat_get_coulomb_cap(di), interval_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) 		 di->sleep_dischrg_sec, di->sleep_chrg_online, bat_status[st]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) 	/* sleep: enough time and discharge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) 	if ((di->sleep_dischrg_sec > time_step) && (!di->sleep_chrg_online)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) 		if (rk816_bat_sleep_dischrg(di))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) 			di->sleep_dischrg_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) 	rk816_bat_save_data(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) 	/* charge/lowpower lock: for battery work to update dsoc and rsoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) 	if ((di->sleep_chrg_online) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) 	    (!di->sleep_chrg_online && di->voltage_avg <= pwroff_vol))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) 		wake_lock_timeout(&di->wake_lock, msecs_to_jiffies(2000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) 	queue_delayed_work(di->bat_monitor_wq, &di->bat_delay_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) 			   msecs_to_jiffies(1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) static void rk816_battery_shutdown(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) 	u8 cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) 	struct rk816_battery *di = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) 	extcon_unregister_notifier(di->cable_edev, EXTCON_CHG_USB_SDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) 				   &di->cable_cg_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) 	extcon_unregister_notifier(di->cable_edev, EXTCON_CHG_USB_DCP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) 				   &di->cable_cg_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) 	extcon_unregister_notifier(di->cable_edev, EXTCON_CHG_USB_CDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) 				   &di->cable_cg_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) 	extcon_unregister_notifier(di->cable_edev, EXTCON_USB_VBUS_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) 				   &di->cable_host_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) 	extcon_unregister_notifier(di->cable_edev, EXTCON_USB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) 				   &di->cable_discnt_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) 	rk816_bat_unregister_fb_notify(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) 	cancel_delayed_work_sync(&di->dc_delay_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) 	cancel_delayed_work_sync(&di->bat_delay_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) 	cancel_delayed_work_sync(&di->calib_delay_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) 	cancel_delayed_work_sync(&di->usb_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) 	cancel_delayed_work_sync(&di->host_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) 	cancel_delayed_work_sync(&di->discnt_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) 	destroy_workqueue(di->bat_monitor_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) 	destroy_workqueue(di->usb_charger_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) 	del_timer(&di->caltimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) 	rk816_bat_set_otg_power(di, USB_OTG_POWER_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) 	if (base2sec(di->boot_base) < REBOOT_PERIOD_SEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) 		cnt = rk816_bat_check_reboot(di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) 		rk816_bat_save_reboot_cnt(di, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) 	BAT_INFO("shutdown: dl=%d rl=%d c=%d v=%d cap=%d f=%d ch=%d otg=%d 5v=%d n=%d mode=%d rest=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) 		 di->dsoc, di->rsoc, di->current_avg, di->voltage_avg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) 		 di->remain_cap, di->fcc, rk816_bat_chrg_online(di),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) 		 di->otg_in, di->otg_pmic5v, cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) 		 di->algo_rest_mode, di->algo_rest_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) static struct platform_driver rk816_battery_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) 	.probe = rk816_battery_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) 	.suspend = rk816_battery_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) 	.resume = rk816_battery_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) 	.shutdown = rk816_battery_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) 		.name = "rk816-battery",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) 		.of_match_table = rk816_battery_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) static int __init battery_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) 	return platform_driver_register(&rk816_battery_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) fs_initcall_sync(battery_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) static void __exit battery_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) 	platform_driver_unregister(&rk816_battery_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) module_exit(battery_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) MODULE_ALIAS("platform:rk816-battery");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) MODULE_AUTHOR("chenjh<chenjh@rock-chips.com>");