^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>");