/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2020 MediaTek Inc. */ #ifndef __MTK_PE5P_H #define __MTK_PE5P_H #include "mtk_charger_algorithm_class.h" #define PE5P_ERR_LEVEL 1 #define PE5P_INFO_LEVEL 2 #define PE5P_DBG_LEVEL 3 #define PE5P_ITA_GAP_WINDOW_SIZE 50 #define PRECISION_ENHANCE 5 #define DISABLE_VBAT_THRESHOLD -1 extern int pe5p_get_log_level(void); #define PE5P_DBG(fmt, ...) \ do { \ if (pe5p_get_log_level() >= PE5P_DBG_LEVEL) \ pr_info("[PE5P]%s " fmt, __func__, ##__VA_ARGS__); \ } while (0) #define PE5P_INFO(fmt, ...) \ do { \ if (pe5p_get_log_level() >= PE5P_INFO_LEVEL) \ pr_info("[PE5P]%s " fmt, __func__, ##__VA_ARGS__); \ } while (0) #define PE5P_ERR(fmt, ...) \ do { \ if (pe5p_get_log_level() >= PE5P_ERR_LEVEL) \ pr_info("[PE5P]%s " fmt, __func__, ##__VA_ARGS__); \ } while (0) enum pe5p_adc_channel { PE5P_ADCCHAN_VBUS = 0, PE5P_ADCCHAN_IBUS, PE5P_ADCCHAN_VBAT, PE5P_ADCCHAN_IBAT, PE5P_ADCCHAN_TBAT, PE5P_ADCCHAN_TCHG, PE5P_ADCCHAN_VOUT, PE5P_ADCCHAN_VSYS, PE5P_ADCCHAN_MAX, }; enum pe5p_algo_state { PE5P_ALGO_INIT = 0, PE5P_ALGO_MEASURE_R, PE5P_ALGO_SS_SWCHG, PE5P_ALGO_SS_DVCHG, PE5P_ALGO_CC_CV, PE5P_ALGO_STOP, PE5P_ALGO_STATE_MAX, }; enum pe5p_thermal_level { PE5P_THERMAL_VERY_COLD = 0, PE5P_THERMAL_COLD, PE5P_THERMAL_VERY_COOL, PE5P_THERMAL_COOL, PE5P_THERMAL_NORMAL, PE5P_THERMAL_WARM, PE5P_THERMAL_VERY_WARM, PE5P_THERMAL_HOT, PE5P_THERMAL_VERY_HOT, PE5P_THERMAL_MAX, }; enum pe5p_rcable_level { PE5P_RCABLE_NORMAL = 0, PE5P_RCABLE_BAD1, PE5P_RCABLE_BAD2, PE5P_RCABLE_BAD3, PE5P_RCABLE_MAX, }; enum pe5p_dvchg_role { PE5P_DVCHG_MASTER = 0, PE5P_DVCHG_SLAVE, PE5P_HVDVCHG_MASTER, PE5P_HVDVCHG_SLAVE, PE5P_BUCK_BSTCHG, PE5P_DVCHG_MAX, }; struct pe5p_ta_status { int temperature; bool ocp; bool otp; bool ovp; }; struct pe5p_ta_auth_data { int vcap_min; int vcap_max; int icap_min; int vta_min; int vta_max; int ita_max; int ita_min; bool pwr_lmt; u8 pdp; bool support_meas_cap; bool support_status; bool support_cc; u32 vta_step; u32 ita_step; u32 ita_gap_per_vstep; }; struct pe5p_algo_data { bool is_dvchg_exist[PE5P_DVCHG_MAX]; /* Thread & Timer */ struct alarm timer; struct task_struct *task; struct mutex lock; struct mutex ext_lock; wait_queue_head_t wq; atomic_t wakeup_thread; atomic_t stop_thread; atomic_t stop_algo; /* Notify */ struct mutex notify_lock; u32 notify; /* Algorithm */ bool inited; bool ta_ready; bool run_once; bool is_swchg_en; bool is_dvchg_en[PE5P_DVCHG_MAX]; bool ignore_ibusucpf; bool force_ta_cv; bool tried_dual_dvchg; bool suspect_ta_cc; struct pe5p_ta_auth_data ta_auth_data; u32 vta_setting; u32 ita_setting; u32 vta_measure; u32 ita_measure; u32 ita_gap_per_vstep; u32 ita_gap_window_idx; u32 ita_gaps[PE5P_ITA_GAP_WINDOW_SIZE]; u32 ichg_setting; u32 aicr_setting; u32 aicr_lmt; u32 aicr_init_lmt; u32 idvchg_cc; u32 idvchg_ss_init; u32 idvchg_term; int vbus_cali; u32 r_sw; u32 r_cable; u32 r_cable_by_swchg; u32 r_bat; u32 r_total; u32 ita_lmt; u32 ita_pwr_lmt; u32 cv_lower_bound; u32 err_retry_cnt; u32 vbusovp; u32 zcv; u32 vbat_cv_no_ircmp; u32 vbat_cv; u32 vbat_ircmp; int vta_comp; int vbat_threshold; /* For checking Ready */ int ref_vbat; /* Vbat with cable in */ bool is_vbat_over_cv; ktime_t stime; enum pe5p_algo_state state; enum pe5p_thermal_level tbat_level; enum pe5p_thermal_level tta_level; enum pe5p_thermal_level tdvchg_level; enum pe5p_thermal_level tswchg_level; int input_current_limit; int cv_limit; }; /* Setting from dtsi */ struct pe5p_algo_desc { u32 polling_interval; /* polling interval */ u32 ta_cv_ss_repeat_tmin; /* min repeat time of ss for TA CV */ u32 vbat_cv; /* vbat constant voltage */ u32 start_soc_min; /* algo start bat low bound */ u32 start_soc_max; /* algo start bat upper bound */ u32 start_vbat_min; /* algo start bat low bound */ u32 start_vbat_max; /* algo start bat upper bound */ u32 idvchg_term; /* terminated current */ u32 idvchg_step; /* input current step */ u32 ita_level[PE5P_RCABLE_MAX]; /* input current */ u32 rcable_level[PE5P_RCABLE_MAX]; /* cable impedance level */ u32 ita_level_dual[PE5P_RCABLE_MAX]; /* input current */ u32 rcable_level_dual[PE5P_RCABLE_MAX]; /* cable impedance level */ u32 idvchg_ss_init; /* SS state init input current */ u32 idvchg_ss_step; /* SS state input current step */ u32 idvchg_ss_step1; /* SS state input current step2 */ u32 idvchg_ss_step2; /* SS state input current step3 */ u32 idvchg_ss_step1_vbat; /* vbat threshold for ic_ss_step2 */ u32 idvchg_ss_step2_vbat; /* vbat threshold for ic_ss_step3 */ u32 ta_blanking; /* wait TA stable */ u32 swchg_aicr; /* CC state swchg input current */ u32 swchg_ichg; /* CC state swchg charging current */ u32 swchg_aicr_ss_init; /* SWCHG_SS state init input current */ u32 swchg_aicr_ss_step; /* SWCHG_SS state input current step */ u32 swchg_off_vbat; /* VBAT to turn off SWCHG */ u32 force_ta_cv_vbat; /* Force TA using CV mode */ u32 chg_time_max; /* max charging time */ int tta_level_def[PE5P_THERMAL_MAX]; /* TA temp level */ int tta_curlmt[PE5P_THERMAL_MAX]; /* TA temp current limit */ int tbat_level_def[PE5P_THERMAL_MAX]; /* BAT temp level */ int tbat_curlmt[PE5P_THERMAL_MAX]; /* BAT temp current limit */ int tdvchg_level_def[PE5P_THERMAL_MAX]; /* DVCHG temp level */ int tdvchg_curlmt[PE5P_THERMAL_MAX]; /* DVCHG temp current limit */ int tswchg_level_def[PE5P_THERMAL_MAX]; /* SWCHG temp level */ int tswchg_curlmt[PE5P_THERMAL_MAX]; /* SWCHG temp current limit */ u32 tta_recovery_area; u32 tbat_recovery_area; u32 tdvchg_recovery_area; u32 tswchg_recovery_area; u32 ifod_threshold; /* FOD current threshold */ u32 rsw_min; /* min rsw */ u32 ircmp_rbat; /* IR compensation's rbat */ u32 ircmp_vclamp; /* IR compensation's vclamp */ u32 vta_cap_min; /* min ta voltage capability */ u32 vta_cap_max; /* max ta voltage capability */ u32 ita_cap_min; /* min ta current capability */ const char **support_ta; /* supported ta name */ u32 support_ta_cnt; /* supported ta count */ bool allow_not_check_ta_status; /* allow not to check ta status */ }; struct pe5p_algo_info { struct device *dev; struct chg_alg_device *alg; struct pe5p_algo_desc *desc; struct pe5p_algo_data *data; }; static inline u32 precise_div(u64 dividend, u64 divisor) { u64 _val = div64_u64(dividend << PRECISION_ENHANCE, divisor); return (u32)((_val + (1 << (PRECISION_ENHANCE - 1))) >> PRECISION_ENHANCE); } static inline u32 percent(u32 val, u32 percent) { return precise_div((u64)val * percent, 100); } static inline u32 div1000(u32 val) { return precise_div(val, 1000); } static inline u32 milli_to_micro(u32 val) { return val * 1000; } static inline int micro_to_milli(int val) { return (val < 0) ? -1 : div1000(val); } extern int pe5p_hal_get_ta_output(struct chg_alg_device *alg, int *mV, int *mA); extern int pe5p_hal_get_ta_status(struct chg_alg_device *alg, struct pe5p_ta_status *status); extern int pe5p_hal_set_ta_cap(struct chg_alg_device *alg, int mV, int mA); extern int pe5p_hal_is_ta_cc(struct chg_alg_device *alg, bool *is_cc); extern int pe5p_hal_set_ta_wdt(struct chg_alg_device *alg, u32 ms); extern int pe5p_hal_enable_ta_wdt(struct chg_alg_device *alg, bool en); extern int pe5p_hal_enable_ta_charging(struct chg_alg_device *alg, bool en, int mV, int mA); extern int pe5p_hal_sync_ta_volt(struct chg_alg_device *alg, u32 mV); extern int pe5p_hal_authenticate_ta(struct chg_alg_device *alg, struct pe5p_ta_auth_data *data); extern int pe5p_hal_send_ta_hardreset(struct chg_alg_device *alg); extern int pe5p_hal_init_hardware(struct chg_alg_device *alg, const char **support_ta, int support_ta_cnt); extern int pe5p_hal_enable_sw_vbusovp(struct chg_alg_device *alg, bool en); extern int pe5p_set_operating_mode(struct chg_alg_device *alg, enum chg_idx chgidx, bool en); extern int pe5p_hal_enable_charging(struct chg_alg_device *alg, enum chg_idx chgidx, bool en); extern int pe5p_hal_dump_registers(struct chg_alg_device *alg, enum chg_idx chgidx); extern int pe5p_hal_enable_hz(struct chg_alg_device *alg, enum chg_idx chgidx, bool en); extern int pe5p_hal_set_vacovp(struct chg_alg_device *alg, enum chg_idx chgidx, u32 mV); extern int pe5p_hal_set_vbusovp(struct chg_alg_device *alg, enum chg_idx chgidx, u32 mV); extern int pe5p_hal_set_ibusocp(struct chg_alg_device *alg, enum chg_idx chgidx, u32 mA); extern int pe5p_hal_set_vbatovp(struct chg_alg_device *alg, enum chg_idx chgidx, u32 mV); extern int pe5p_hal_set_ibatocp(struct chg_alg_device *alg, enum chg_idx chgidx, u32 mA); extern int pe5p_hal_set_vbatovp_alarm(struct chg_alg_device *alg, enum chg_idx chgidx, u32 mV); extern int pe5p_hal_reset_vbatovp_alarm(struct chg_alg_device *alg, enum chg_idx chgidx); extern int pe5p_hal_set_vbusovp_alarm(struct chg_alg_device *alg, enum chg_idx chgidx, u32 mV); extern int pe5p_hal_reset_vbusovp_alarm(struct chg_alg_device *alg, enum chg_idx chgidx); extern int pe5p_hal_get_adc(struct chg_alg_device *alg, enum chg_idx chgidx, enum pe5p_adc_channel chan, int *val); extern int pe5p_hal_get_soc(struct chg_alg_device *alg, u32 *soc); extern int pe5p_hal_is_pd_adapter_ready(struct chg_alg_device *alg); extern int pe5p_hal_set_ichg(struct chg_alg_device *alg, enum chg_idx chgidx, u32 mA); extern int pe5p_hal_set_aicr(struct chg_alg_device *alg, enum chg_idx chgidx, u32 mA); extern int pe5p_hal_get_ichg(struct chg_alg_device *alg, enum chg_idx chgidx, u32 *mA); extern int pe5p_hal_get_aicr(struct chg_alg_device *alg, enum chg_idx chgidx, u32 *mA); extern int pe5p_hal_is_vbuslowerr(struct chg_alg_device *alg, enum chg_idx chgidx, bool *err); extern int pe5p_hal_get_adc_accuracy(struct chg_alg_device *alg, enum chg_idx chgidx, enum pe5p_adc_channel chan, int *val); extern int pe5p_hal_init_chip(struct chg_alg_device *alg, enum chg_idx chgidx); #endif /* __MTK_PE5P_H */