blob: 2c284433764d66fee290266de98516e1e9a50f94 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*/
#ifndef __SMB5_CHARGER_H
#define __SMB5_CHARGER_H
#include <linux/alarmtimer.h>
#include <linux/ktime.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/consumer.h>
#include <linux/extcon-provider.h>
#include "storm-watch.h"
enum print_reason {
PR_INTERRUPT = BIT(0),
PR_REGISTER = BIT(1),
PR_MISC = BIT(2),
PR_PARALLEL = BIT(3),
PR_OTG = BIT(4),
PR_WLS = BIT(5),
};
#define DEFAULT_VOTER "DEFAULT_VOTER"
#define USER_VOTER "USER_VOTER"
#define PD_VOTER "PD_VOTER"
#define DCP_VOTER "DCP_VOTER"
#define QC_VOTER "QC_VOTER"
#define USB_PSY_VOTER "USB_PSY_VOTER"
#define PL_TAPER_WORK_RUNNING_VOTER "PL_TAPER_WORK_RUNNING_VOTER"
#define USBIN_V_VOTER "USBIN_V_VOTER"
#define CHG_STATE_VOTER "CHG_STATE_VOTER"
#define TAPER_END_VOTER "TAPER_END_VOTER"
#define THERMAL_DAEMON_VOTER "THERMAL_DAEMON_VOTER"
#define BOOST_BACK_VOTER "BOOST_BACK_VOTER"
#define MICRO_USB_VOTER "MICRO_USB_VOTER"
#define DEBUG_BOARD_VOTER "DEBUG_BOARD_VOTER"
#define PD_SUSPEND_SUPPORTED_VOTER "PD_SUSPEND_SUPPORTED_VOTER"
#define PL_DELAY_VOTER "PL_DELAY_VOTER"
#define CTM_VOTER "CTM_VOTER"
#define SW_QC3_VOTER "SW_QC3_VOTER"
#define AICL_RERUN_VOTER "AICL_RERUN_VOTER"
#define SW_ICL_MAX_VOTER "SW_ICL_MAX_VOTER"
#define PL_QNOVO_VOTER "PL_QNOVO_VOTER"
#define QNOVO_VOTER "QNOVO_VOTER"
#define BATT_PROFILE_VOTER "BATT_PROFILE_VOTER"
#define OTG_DELAY_VOTER "OTG_DELAY_VOTER"
#define USBIN_I_VOTER "USBIN_I_VOTER"
#define WEAK_CHARGER_VOTER "WEAK_CHARGER_VOTER"
#define OTG_VOTER "OTG_VOTER"
#define PL_FCC_LOW_VOTER "PL_FCC_LOW_VOTER"
#define WBC_VOTER "WBC_VOTER"
#define HW_LIMIT_VOTER "HW_LIMIT_VOTER"
#define PL_SMB_EN_VOTER "PL_SMB_EN_VOTER"
#define FORCE_RECHARGE_VOTER "FORCE_RECHARGE_VOTER"
#define LPD_VOTER "LPD_VOTER"
#define FCC_STEPPER_VOTER "FCC_STEPPER_VOTER"
#define SW_THERM_REGULATION_VOTER "SW_THERM_REGULATION_VOTER"
#define BOOST_BACK_STORM_COUNT 3
#define WEAK_CHG_STORM_COUNT 8
#define VBAT_TO_VRAW_ADC(v) div_u64((u64)v * 1000000UL, 194637UL)
#define ADC_CHG_TERM_MASK 32767
enum smb_mode {
PARALLEL_MASTER = 0,
PARALLEL_SLAVE,
NUM_MODES,
};
enum sink_src_mode {
SINK_MODE,
SRC_MODE,
UNATTACHED_MODE,
};
enum qc2_non_comp_voltage {
QC2_COMPLIANT,
QC2_NON_COMPLIANT_9V,
QC2_NON_COMPLIANT_12V
};
enum {
BOOST_BACK_WA = BIT(0),
SW_THERM_REGULATION_WA = BIT(1),
};
enum smb_irq_index {
/* CHGR */
CHGR_ERROR_IRQ = 0,
CHG_STATE_CHANGE_IRQ,
STEP_CHG_STATE_CHANGE_IRQ,
STEP_CHG_SOC_UPDATE_FAIL_IRQ,
STEP_CHG_SOC_UPDATE_REQ_IRQ,
FG_FVCAL_QUALIFIED_IRQ,
VPH_ALARM_IRQ,
VPH_DROP_PRECHG_IRQ,
/* DCDC */
OTG_FAIL_IRQ,
OTG_OC_DISABLE_SW_IRQ,
OTG_OC_HICCUP_IRQ,
BSM_ACTIVE_IRQ,
HIGH_DUTY_CYCLE_IRQ,
INPUT_CURRENT_LIMITING_IRQ,
CONCURRENT_MODE_DISABLE_IRQ,
SWITCHER_POWER_OK_IRQ,
/* BATIF */
BAT_TEMP_IRQ,
ALL_CHNL_CONV_DONE_IRQ,
BAT_OV_IRQ,
BAT_LOW_IRQ,
BAT_THERM_OR_ID_MISSING_IRQ,
BAT_TERMINAL_MISSING_IRQ,
BUCK_OC_IRQ,
VPH_OV_IRQ,
/* USB */
USBIN_COLLAPSE_IRQ,
USBIN_VASHDN_IRQ,
USBIN_UV_IRQ,
USBIN_OV_IRQ,
USBIN_PLUGIN_IRQ,
USBIN_REVI_CHANGE_IRQ,
USBIN_SRC_CHANGE_IRQ,
USBIN_ICL_CHANGE_IRQ,
/* DC */
DCIN_VASHDN_IRQ,
DCIN_UV_IRQ,
DCIN_OV_IRQ,
DCIN_PLUGIN_IRQ,
DCIN_REVI_IRQ,
DCIN_PON_IRQ,
DCIN_EN_IRQ,
/* TYPEC */
TYPEC_OR_RID_DETECTION_CHANGE_IRQ,
TYPEC_VPD_DETECT_IRQ,
TYPEC_CC_STATE_CHANGE_IRQ,
TYPEC_VCONN_OC_IRQ,
TYPEC_VBUS_CHANGE_IRQ,
TYPEC_ATTACH_DETACH_IRQ,
TYPEC_LEGACY_CABLE_DETECT_IRQ,
TYPEC_TRY_SNK_SRC_DETECT_IRQ,
/* MISC */
WDOG_SNARL_IRQ,
WDOG_BARK_IRQ,
AICL_FAIL_IRQ,
AICL_DONE_IRQ,
SMB_EN_IRQ,
IMP_TRIGGER_IRQ,
TEMP_CHANGE_IRQ,
TEMP_CHANGE_SMB_IRQ,
/* FLASH */
VREG_OK_IRQ,
ILIM_S2_IRQ,
ILIM_S1_IRQ,
VOUT_DOWN_IRQ,
VOUT_UP_IRQ,
FLASH_STATE_CHANGE_IRQ,
TORCH_REQ_IRQ,
FLASH_EN_IRQ,
/* END */
SMB_IRQ_MAX,
};
enum float_options {
FLOAT_DCP = 1,
FLOAT_SDP = 2,
DISABLE_CHARGING = 3,
SUSPEND_INPUT = 4,
};
enum chg_term_config_src {
ITERM_SRC_UNSPECIFIED,
ITERM_SRC_ADC,
ITERM_SRC_ANALOG
};
struct smb_irq_info {
const char *name;
const irq_handler_t handler;
const bool wake;
const struct storm_watch storm_data;
struct smb_irq_data *irq_data;
int irq;
};
static const unsigned int smblib_extcon_cable[] = {
EXTCON_USB,
EXTCON_USB_HOST,
EXTCON_NONE,
};
enum lpd_reason {
LPD_NONE,
LPD_MOISTURE_DETECTED,
LPD_FLOATING_CABLE,
};
/* Following states are applicable only for floating cable during LPD */
enum lpd_stage {
/* initial stage */
LPD_STAGE_NONE,
/* started and ongoing */
LPD_STAGE_FLOAT,
/* cancel if started, or don't start */
LPD_STAGE_FLOAT_CANCEL,
/* confirmed and mitigation measures taken for 60 s */
LPD_STAGE_COMMIT,
};
enum thermal_status_levels {
TEMP_SHUT_DOWN = 0,
TEMP_SHUT_DOWN_SMB,
TEMP_ALERT_LEVEL,
TEMP_ABOVE_RANGE,
TEMP_WITHIN_RANGE,
TEMP_BELOW_RANGE,
};
/* EXTCON_USB and EXTCON_USB_HOST are mutually exclusive */
static const u32 smblib_extcon_exclusive[] = {0x3, 0};
struct smb_regulator {
struct regulator_dev *rdev;
struct regulator_desc rdesc;
};
struct smb_irq_data {
void *parent_data;
const char *name;
struct storm_watch storm_data;
};
struct smb_chg_param {
const char *name;
u16 reg;
int min_u;
int max_u;
int step_u;
int (*get_proc)(struct smb_chg_param *param,
u8 val_raw);
int (*set_proc)(struct smb_chg_param *param,
int val_u,
u8 *val_raw);
};
struct buck_boost_freq {
int freq_khz;
u8 val;
};
struct smb_chg_freq {
unsigned int freq_5V;
unsigned int freq_6V_8V;
unsigned int freq_9V;
unsigned int freq_12V;
unsigned int freq_removal;
unsigned int freq_below_otg_threshold;
unsigned int freq_above_otg_threshold;
};
struct smb_params {
struct smb_chg_param fcc;
struct smb_chg_param fv;
struct smb_chg_param usb_icl;
struct smb_chg_param icl_max_stat;
struct smb_chg_param icl_stat;
struct smb_chg_param otg_cl;
struct smb_chg_param dc_icl;
struct smb_chg_param jeita_cc_comp_hot;
struct smb_chg_param jeita_cc_comp_cold;
struct smb_chg_param freq_switcher;
};
struct parallel_params {
struct power_supply *psy;
};
struct smb_iio {
struct iio_channel *temp_chan;
struct iio_channel *usbin_i_chan;
struct iio_channel *usbin_v_chan;
struct iio_channel *mid_chan;
struct iio_channel *batt_i_chan;
struct iio_channel *connector_temp_chan;
struct iio_channel *sbux_chan;
struct iio_channel *vph_v_chan;
struct iio_channel *die_temp_chan;
struct iio_channel *skin_temp_chan;
struct iio_channel *smb_temp_chan;
};
struct smb_charger {
struct device *dev;
char *name;
struct regmap *regmap;
struct smb_irq_info *irq_info;
struct smb_params param;
struct smb_iio iio;
int *debug_mask;
int pd_disabled;
enum smb_mode mode;
struct smb_chg_freq chg_freq;
int smb_version;
int otg_delay_ms;
int weak_chg_icl_ua;
bool pd_not_supported;
/* locks */
struct mutex smb_lock;
struct mutex ps_change_lock;
/* power supplies */
struct power_supply *batt_psy;
struct power_supply *usb_psy;
struct power_supply *dc_psy;
struct power_supply *bms_psy;
struct power_supply *usb_main_psy;
struct power_supply *usb_port_psy;
struct power_supply *wls_psy;
enum power_supply_type real_charger_type;
/* notifiers */
struct notifier_block nb;
/* parallel charging */
struct parallel_params pl;
/* regulators */
struct smb_regulator *vbus_vreg;
struct smb_regulator *vconn_vreg;
struct regulator *dpdm_reg;
/* votables */
struct votable *dc_suspend_votable;
struct votable *fcc_votable;
struct votable *fv_votable;
struct votable *usb_icl_votable;
struct votable *awake_votable;
struct votable *pl_disable_votable;
struct votable *chg_disable_votable;
struct votable *pl_enable_votable_indirect;
struct votable *usb_irq_enable_votable;
struct votable *cp_disable_votable;
struct votable *wdog_snarl_irq_en_votable;
/* work */
struct work_struct bms_update_work;
struct work_struct pl_update_work;
struct work_struct jeita_update_work;
struct delayed_work ps_change_timeout_work;
struct delayed_work clear_hdc_work;
struct delayed_work icl_change_work;
struct delayed_work pl_enable_work;
struct delayed_work uusb_otg_work;
struct delayed_work bb_removal_work;
struct delayed_work lpd_ra_open_work;
struct delayed_work lpd_detach_work;
struct delayed_work thermal_regulation_work;
struct alarm lpd_recheck_timer;
/* secondary charger config */
bool sec_pl_present;
bool sec_cp_present;
int sec_chg_selected;
int cp_reason;
/* pd */
int voltage_min_uv;
int voltage_max_uv;
int pd_active;
bool pd_hard_reset;
bool pr_swap_in_progress;
bool early_usb_attach;
bool ok_to_pd;
bool typec_legacy;
/* cached status */
bool system_suspend_supported;
int boost_threshold_ua;
int system_temp_level;
int thermal_levels;
int *thermal_mitigation;
int dcp_icl_ua;
int fake_capacity;
int fake_batt_status;
bool step_chg_enabled;
bool sw_jeita_enabled;
bool is_hdc;
bool chg_done;
int connector_type;
bool otg_en;
bool suspend_input_on_debug_batt;
int default_icl_ua;
int otg_cl_ua;
bool uusb_apsd_rerun_done;
bool typec_present;
int fake_input_current_limited;
int typec_mode;
int usb_icl_change_irq_enabled;
u32 jeita_status;
u8 float_cfg;
bool use_extcon;
bool otg_present;
bool hvdcp_disable;
int hw_max_icl_ua;
int auto_recharge_soc;
enum sink_src_mode sink_src_mode;
bool jeita_configured;
int charger_temp_max;
int smb_temp_max;
u8 typec_try_mode;
enum lpd_stage lpd_stage;
enum lpd_reason lpd_reason;
bool fcc_stepper_enable;
int die_temp;
int smb_temp;
int skin_temp;
int connector_temp;
int thermal_status;
int main_fcc_max;
/* workaround flag */
u32 wa_flags;
int boost_current_ua;
int qc2_max_pulses;
enum qc2_non_comp_voltage qc2_unsupported_voltage;
/* extcon for VBUS / ID notification to USB for uUSB */
struct extcon_dev *extcon;
/* battery profile */
int batt_profile_fcc_ua;
int batt_profile_fv_uv;
int usb_icl_delta_ua;
int pulse_cnt;
int die_health;
int connector_health;
/* flash */
u32 flash_derating_soc;
u32 flash_disable_soc;
u32 headroom_mode;
bool flash_init_done;
bool flash_active;
/* wireless */
int wireless_vout;
};
int smblib_read(struct smb_charger *chg, u16 addr, u8 *val);
int smblib_masked_write(struct smb_charger *chg, u16 addr, u8 mask, u8 val);
int smblib_write(struct smb_charger *chg, u16 addr, u8 val);
int smblib_batch_write(struct smb_charger *chg, u16 addr, u8 *val, int count);
int smblib_batch_read(struct smb_charger *chg, u16 addr, u8 *val, int count);
int smblib_get_charge_param(struct smb_charger *chg,
struct smb_chg_param *param, int *val_u);
int smblib_get_usb_suspend(struct smb_charger *chg, int *suspend);
int smblib_enable_charging(struct smb_charger *chg, bool enable);
int smblib_set_charge_param(struct smb_charger *chg,
struct smb_chg_param *param, int val_u);
int smblib_set_usb_suspend(struct smb_charger *chg, bool suspend);
int smblib_set_dc_suspend(struct smb_charger *chg, bool suspend);
int smblib_mapping_soc_from_field_value(struct smb_chg_param *param,
int val_u, u8 *val_raw);
int smblib_mapping_cc_delta_to_field_value(struct smb_chg_param *param,
u8 val_raw);
int smblib_mapping_cc_delta_from_field_value(struct smb_chg_param *param,
int val_u, u8 *val_raw);
int smblib_set_chg_freq(struct smb_chg_param *param,
int val_u, u8 *val_raw);
int smblib_set_prop_boost_current(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_vbus_regulator_enable(struct regulator_dev *rdev);
int smblib_vbus_regulator_disable(struct regulator_dev *rdev);
int smblib_vbus_regulator_is_enabled(struct regulator_dev *rdev);
int smblib_vconn_regulator_enable(struct regulator_dev *rdev);
int smblib_vconn_regulator_disable(struct regulator_dev *rdev);
int smblib_vconn_regulator_is_enabled(struct regulator_dev *rdev);
irqreturn_t default_irq_handler(int irq, void *data);
irqreturn_t chg_state_change_irq_handler(int irq, void *data);
irqreturn_t batt_temp_changed_irq_handler(int irq, void *data);
irqreturn_t batt_psy_changed_irq_handler(int irq, void *data);
irqreturn_t usbin_uv_irq_handler(int irq, void *data);
irqreturn_t usb_plugin_irq_handler(int irq, void *data);
irqreturn_t usb_source_change_irq_handler(int irq, void *data);
irqreturn_t icl_change_irq_handler(int irq, void *data);
irqreturn_t typec_state_change_irq_handler(int irq, void *data);
irqreturn_t typec_attach_detach_irq_handler(int irq, void *data);
irqreturn_t dc_plugin_irq_handler(int irq, void *data);
irqreturn_t high_duty_cycle_irq_handler(int irq, void *data);
irqreturn_t switcher_power_ok_irq_handler(int irq, void *data);
irqreturn_t wdog_snarl_irq_handler(int irq, void *data);
irqreturn_t wdog_bark_irq_handler(int irq, void *data);
irqreturn_t typec_or_rid_detection_change_irq_handler(int irq, void *data);
int smblib_get_prop_input_suspend(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_batt_present(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_batt_capacity(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_batt_status(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_batt_charge_type(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_batt_charge_done(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_batt_health(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_system_temp_level(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_system_temp_level_max(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_input_current_limited(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_batt_iterm(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_set_prop_input_suspend(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_batt_capacity(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_batt_status(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_system_temp_level(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_input_current_limited(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_get_prop_dc_present(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_dc_online(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_dc_current_max(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_set_prop_dc_current_max(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_get_prop_dc_voltage_now(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_dc_voltage_max(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_set_prop_voltage_wls_output(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_get_prop_usb_present(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_usb_online(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_usb_suspend(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_usb_voltage_max(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_usb_voltage_now(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_low_power(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_usb_current_now(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_typec_cc_orientation(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_typec_select_rp(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_typec_power_role(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_input_current_settled(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_input_voltage_settled(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_pd_in_hard_reset(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_pe_start(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_charger_temp(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_die_health(struct smb_charger *chg);
int smblib_get_prop_connector_health(struct smb_charger *chg);
int smblib_set_prop_pd_current_max(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_sdp_current_max(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_pd_voltage_max(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_pd_voltage_min(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_typec_power_role(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_typec_select_rp(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_pd_active(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_pd_in_hard_reset(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_ship_mode(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_rechg_soc_thresh(struct smb_charger *chg,
const union power_supply_propval *val);
void smblib_suspend_on_debug_battery(struct smb_charger *chg);
int smblib_rerun_apsd_if_required(struct smb_charger *chg);
int smblib_get_prop_fcc_delta(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_thermal_threshold(struct smb_charger *chg, u16 addr, int *val);
int smblib_dp_dm(struct smb_charger *chg, int val);
int smblib_disable_hw_jeita(struct smb_charger *chg, bool disable);
int smblib_rerun_aicl(struct smb_charger *chg);
int smblib_set_icl_current(struct smb_charger *chg, int icl_ua);
int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua);
int smblib_get_charge_current(struct smb_charger *chg, int *total_current_ua);
int smblib_get_prop_pr_swap_in_progress(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_get_prop_from_bms(struct smb_charger *chg,
enum power_supply_property psp,
union power_supply_propval *val);
int smblib_get_iio_channel(struct smb_charger *chg, const char *propname,
struct iio_channel **chan);
int smblib_read_iio_channel(struct smb_charger *chg, struct iio_channel *chan,
int div, int *data);
int smblib_configure_hvdcp_apsd(struct smb_charger *chg, bool enable);
int smblib_icl_override(struct smb_charger *chg, bool override);
enum alarmtimer_restart smblib_lpd_recheck_timer(struct alarm *alarm,
ktime_t time);
int smblib_toggle_smb_en(struct smb_charger *chg, int toggle);
void smblib_hvdcp_detect_enable(struct smb_charger *chg, bool enable);
void smblib_apsd_enable(struct smb_charger *chg, bool enable);
int smblib_init(struct smb_charger *chg);
int smblib_deinit(struct smb_charger *chg);
#endif /* __SMB5_CHARGER_H */