Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f49c7f3f authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "power: smb5: Fix AICL configuration for pmi632"

parents 0b297c15 5437ac9c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2015-2017 The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2017, 2019 The Linux Foundation. All rights reserved.
 */

#include <linux/debugfs.h>
@@ -13,7 +13,7 @@

#include <linux/pmic-voter.h>

#define NUM_MAX_CLIENTS		16
#define NUM_MAX_CLIENTS		32
#define DEBUG_FORCE_CLIENT	"DEBUG_FORCE_CLIENT"

static DEFINE_SPINLOCK(votable_list_slock);
+49 −51
Original line number Diff line number Diff line
@@ -206,6 +206,7 @@ struct smb_dt_props {
	bool			no_battery;
	bool			hvdcp_disable;
	bool			hvdcp_autonomous;
	bool			adc_based_aicl;
	int			sec_charger_config;
	int			auto_recharge_soc;
	int			auto_recharge_vbat_mv;
@@ -549,6 +550,9 @@ static int smb5_parse_dt_misc(struct smb5 *chip, struct device_node *node)
	chip->dt.disable_suspend_on_collapse = of_property_read_bool(node,
					"qcom,disable-suspend-on-collapse");

	chip->dt.adc_based_aicl = of_property_read_bool(node,
					"qcom,adc-based-aicl");

	return 0;
}

@@ -560,18 +564,11 @@ static int smb5_parse_dt_adc_channels(struct smb_charger *chg)
	if (rc < 0)
		return rc;

	if (!chg->iio.mid_chan) {
	rc = smblib_get_iio_channel(chg, "usb_in_voltage",
					&chg->iio.usbin_v_chan);
	if (rc < 0)
		return rc;

		if (!chg->iio.usbin_v_chan) {
			dev_err(chg->dev, "No voltage channel defined\n");
			return -EINVAL;
		}
	}

	rc = smblib_get_iio_channel(chg, "chg_temp", &chg->iio.temp_chan);
	if (rc < 0)
		return rc;
@@ -1288,6 +1285,7 @@ static enum power_supply_property smb5_dc_props[] = {
	POWER_SUPPLY_PROP_VOLTAGE_MAX,
	POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION,
	POWER_SUPPLY_PROP_REAL_TYPE,
	POWER_SUPPLY_PROP_DC_RESET,
};

static int smb5_dc_get_prop(struct power_supply *psy,
@@ -1322,6 +1320,8 @@ static int smb5_dc_get_prop(struct power_supply *psy,
		break;
	case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION:
		rc = smblib_get_prop_voltage_wls_output(chg, val);
	case POWER_SUPPLY_PROP_DC_RESET:
		val->intval = 0;
		break;
	default:
		return -EINVAL;
@@ -1352,6 +1352,9 @@ static int smb5_dc_set_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION:
		rc = smblib_set_prop_voltage_wls_output(chg, val);
		break;
	case POWER_SUPPLY_PROP_DC_RESET:
		rc = smblib_set_prop_dc_reset(chg);
		break;
	default:
		return -EINVAL;
	}
@@ -1917,14 +1920,17 @@ static int smb5_configure_typec(struct smb_charger *chg)
		return rc;
	}

	if (chg->smb_version != PMI632_SUBTYPE) {
		rc = smblib_masked_write(chg, USBIN_LOAD_CFG_REG,
		USBIN_IN_COLLAPSE_GF_SEL_MASK | USBIN_AICL_STEP_TIMING_SEL_MASK,
				USBIN_IN_COLLAPSE_GF_SEL_MASK |
				USBIN_AICL_STEP_TIMING_SEL_MASK,
				0);
		if (rc < 0) {
			dev_err(chg->dev,
				"Couldn't set USBIN_LOAD_CFG_REG rc=%d\n", rc);
			return rc;
		}
	}

	/* Set CC threshold to 1.6 V in source mode */
	rc = smblib_masked_write(chg, TYPE_C_EXIT_STATE_CFG_REG,
@@ -2215,40 +2221,32 @@ static int smb5_configure_recharging(struct smb5 *chip)
static int smb5_configure_float_charger(struct smb5 *chip)
{
	int rc = 0;
	u8 val = 0;
	struct smb_charger *chg = &chip->chg;

	/* configure float charger options */
	switch (chip->dt.float_option) {
	case FLOAT_DCP:
		rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
				FLOAT_OPTIONS_MASK, 0);
		break;
	case FLOAT_SDP:
		rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
				FLOAT_OPTIONS_MASK, FORCE_FLOAT_SDP_CFG_BIT);
		val = FORCE_FLOAT_SDP_CFG_BIT;
		break;
	case DISABLE_CHARGING:
		rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
				FLOAT_OPTIONS_MASK, FLOAT_DIS_CHGING_CFG_BIT);
		val = FLOAT_DIS_CHGING_CFG_BIT;
		break;
	case SUSPEND_INPUT:
		rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
				FLOAT_OPTIONS_MASK, SUSPEND_FLOAT_CFG_BIT);
		val = SUSPEND_FLOAT_CFG_BIT;
		break;
	case FLOAT_DCP:
	default:
		rc = 0;
		val = 0;
		break;
	}

	chg->float_cfg = val;
	/* Update float charger setting and set DCD timeout 300ms */
	rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
				FLOAT_OPTIONS_MASK | DCD_TIMEOUT_SEL_BIT, val);
	if (rc < 0) {
		dev_err(chg->dev, "Couldn't configure float charger options rc=%d\n",
			rc);
		return rc;
	}

	rc = smblib_read(chg, USBIN_OPTIONS_2_CFG_REG, &chg->float_cfg);
	if (rc < 0) {
		dev_err(chg->dev, "Couldn't read float charger options rc=%d\n",
		dev_err(chg->dev, "Couldn't change float charger setting rc=%d\n",
			rc);
		return rc;
	}
@@ -2434,15 +2432,16 @@ static int smb5_init_hw(struct smb5 *chip)
		return rc;

	/*
	 * AICL configuration:
	 * start from min and AICL ADC disable, and enable aicl rerun
	 * AICL configuration: enable aicl and aicl rerun and based on DT
	 * configuration enable/disable ADB based AICL and Suspend on collapse.
	 */
	if (chg->smb_version != PMI632_SUBTYPE) {
	mask = USBIN_AICL_PERIODIC_RERUN_EN_BIT | USBIN_AICL_ADC_EN_BIT
			| USBIN_AICL_EN_BIT | SUSPEND_ON_COLLAPSE_USBIN_BIT;
	val = USBIN_AICL_PERIODIC_RERUN_EN_BIT | USBIN_AICL_EN_BIT;
	if (!chip->dt.disable_suspend_on_collapse)
		val |= SUSPEND_ON_COLLAPSE_USBIN_BIT;
	if (chip->dt.adc_based_aicl)
		val |= USBIN_AICL_ADC_EN_BIT;

	rc = smblib_masked_write(chg, USBIN_AICL_OPTIONS_CFG_REG,
			mask, val);
@@ -2450,7 +2449,6 @@ static int smb5_init_hw(struct smb5 *chip)
		dev_err(chg->dev, "Couldn't config AICL rc=%d\n", rc);
		return rc;
	}
	}

	rc = smblib_write(chg, AICL_RERUN_TIME_CFG_REG,
				AICL_RERUN_TIME_12S_VAL);
+130 −8
Original line number Diff line number Diff line
@@ -322,11 +322,14 @@ static void smblib_notify_extcon_props(struct smb_charger *chg, int id)
		val.intval = ((prop_val.intval == 2) ? 1 : 0);
		extcon_set_property(chg->extcon, id,
				EXTCON_PROP_USB_TYPEC_POLARITY, val);
	}

		val.intval = true;
		extcon_set_property(chg->extcon, id,
				EXTCON_PROP_USB_SS, val);
	} else if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) {
		val.intval = false;
		extcon_set_property(chg->extcon, id,
				EXTCON_PROP_USB_SS, val);
	}
}

static void smblib_notify_device_mode(struct smb_charger *chg, bool enable)
@@ -2923,6 +2926,57 @@ int smblib_set_prop_voltage_wls_output(struct smb_charger *chg,
	return rc;
}

int smblib_set_prop_dc_reset(struct smb_charger *chg)
{
	int rc;

	rc = vote(chg->dc_suspend_votable, VOUT_VOTER, true, 0);
	if (rc < 0) {
		smblib_err(chg, "Couldn't suspend DC rc=%d\n", rc);
		return rc;
	}

	rc = smblib_masked_write(chg, DCIN_CMD_IL_REG, DCIN_EN_MASK,
				DCIN_EN_OVERRIDE_BIT);
	if (rc < 0) {
		smblib_err(chg, "Couldn't set DCIN_EN_OVERRIDE_BIT rc=%d\n",
			rc);
		return rc;
	}

	rc = smblib_write(chg, DCIN_CMD_PON_REG, DCIN_PON_BIT | MID_CHG_BIT);
	if (rc < 0) {
		smblib_err(chg, "Couldn't write %d to DCIN_CMD_PON_REG rc=%d\n",
			DCIN_PON_BIT | MID_CHG_BIT, rc);
		return rc;
	}

	/* Wait for 10ms to allow the charge to get drained */
	usleep_range(10000, 10010);

	rc = smblib_write(chg, DCIN_CMD_PON_REG, 0);
	if (rc < 0) {
		smblib_err(chg, "Couldn't clear DCIN_CMD_PON_REG rc=%d\n", rc);
		return rc;
	}

	rc = smblib_masked_write(chg, DCIN_CMD_IL_REG, DCIN_EN_MASK, 0);
	if (rc < 0) {
		smblib_err(chg, "Couldn't clear DCIN_EN_OVERRIDE_BIT rc=%d\n",
			rc);
		return rc;
	}

	rc = vote(chg->dc_suspend_votable, VOUT_VOTER, false, 0);
	if (rc < 0) {
		smblib_err(chg, "Couldn't unsuspend  DC rc=%d\n", rc);
		return rc;
	}

	smblib_dbg(chg, PR_MISC, "Wireless charger removal detection successful\n");
	return rc;
}

/*******************
 * USB PSY GETTERS *
 *******************/
@@ -3643,7 +3697,7 @@ int smblib_get_prop_scope(struct smb_charger *chg,
	return 0;
}

int smblib_get_prop_connector_health(struct smb_charger *chg)
static int smblib_get_typec_connector_temp_status(struct smb_charger *chg)
{
	int rc;
	u8 stat;
@@ -3686,6 +3740,56 @@ int smblib_get_prop_connector_health(struct smb_charger *chg)
	return POWER_SUPPLY_HEALTH_COOL;
}

static int smblib_get_skin_temp_status(struct smb_charger *chg)
{
	int rc;
	u8 stat;

	rc = smblib_read(chg, SKIN_TEMP_STATUS_REG, &stat);
	if (rc < 0) {
		smblib_err(chg, "Couldn't read SKIN_TEMP_STATUS_REG, rc=%d\n",
				rc);
		return POWER_SUPPLY_HEALTH_UNKNOWN;
	}

	if (stat & SKIN_TEMP_RST_BIT)
		return POWER_SUPPLY_HEALTH_OVERHEAT;

	if (stat & SKIN_TEMP_UB_BIT)
		return POWER_SUPPLY_HEALTH_HOT;

	if (stat & SKIN_TEMP_LB_BIT)
		return POWER_SUPPLY_HEALTH_WARM;

	return POWER_SUPPLY_HEALTH_COOL;
}

int smblib_get_prop_connector_health(struct smb_charger *chg)
{
	bool dc_present, usb_present;
	int input_present;
	int rc;

	rc = smblib_is_input_present(chg, &input_present);
	if (rc < 0)
		return POWER_SUPPLY_HEALTH_UNKNOWN;

	dc_present = input_present & INPUT_PRESENT_DC;
	usb_present = input_present & INPUT_PRESENT_USB;

	if (usb_present)
		return smblib_get_typec_connector_temp_status(chg);

	/*
	 * In PM8150B, SKIN channel measures Wireless charger receiver
	 * temp, used to regulate DC ICL.
	 */
	if (chg->smb_version == PM8150B_SUBTYPE && dc_present)
		return smblib_get_skin_temp_status(chg);

	return POWER_SUPPLY_HEALTH_COOL;
}

static int get_rp_based_dcp_current(struct smb_charger *chg, int typec_mode)
{
	int rp_ua;
@@ -3735,12 +3839,12 @@ static int smblib_handle_usb_current(struct smb_charger *chg,
				 * Confiugure USB500 mode if Float charger is
				 * configured for SDP mode.
				 */
				rc = set_sdp_current(chg, USBIN_500MA);
				rc = vote(chg->usb_icl_votable,
					SW_ICL_MAX_VOTER, true, USBIN_500MA);
				if (rc < 0)
					smblib_err(chg,
						"Couldn't set SDP ICL rc=%d\n",
						rc);

				return rc;
			}

@@ -4854,6 +4958,11 @@ static void update_sw_icl_max(struct smb_charger *chg, int pst)
	if (chg->pd_active)
		return;

	if (chg->typec_mode == POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) {
		vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, 500000);
		return;
	}

	/*
	 * HVDCP 2/3, handled separately
	 */
@@ -5138,6 +5247,14 @@ static void typec_src_insertion(struct smb_charger *chg)
		smblib_hvdcp_detect_try_enable(chg, true);
}

static void typec_ra_ra_insertion(struct smb_charger *chg)
{
	vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, 500000);
	vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0);
	chg->ok_to_pd = false;
	smblib_hvdcp_detect_enable(chg, true);
}

static void typec_sink_removal(struct smb_charger *chg)
{
	int rc;
@@ -5437,7 +5554,11 @@ irqreturn_t typec_attach_detach_irq_handler(int irq, void *data)
			return IRQ_HANDLED;
		}

		if (stat & SNK_SRC_MODE_BIT) {
		if (smblib_get_prop_dfp_mode(chg) ==
				POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) {
			chg->sink_src_mode = AUDIO_ACCESS_MODE;
			typec_ra_ra_insertion(chg);
		} else if (stat & SNK_SRC_MODE_BIT) {
			if (smblib_src_lpd(chg))
				return IRQ_HANDLED;
			chg->sink_src_mode = SRC_MODE;
@@ -5453,6 +5574,7 @@ irqreturn_t typec_attach_detach_irq_handler(int irq, void *data)
			typec_sink_removal(chg);
			break;
		case SINK_MODE:
		case AUDIO_ACCESS_MODE:
			typec_src_removal(chg);
			break;
		case UNATTACHED_MODE:
+3 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ enum print_reason {
#define USBOV_DBC_VOTER			"USBOV_DBC_VOTER"
#define CHG_TERMINATION_VOTER		"CHG_TERMINATION_VOTER"
#define THERMAL_THROTTLE_VOTER		"THERMAL_THROTTLE_VOTER"
#define VOUT_VOTER			"VOUT_VOTER"

#define BOOST_BACK_STORM_COUNT	3
#define WEAK_CHG_STORM_COUNT	8
@@ -94,6 +95,7 @@ enum smb_mode {
enum sink_src_mode {
	SINK_MODE,
	SRC_MODE,
	AUDIO_ACCESS_MODE,
	UNATTACHED_MODE,
};

@@ -632,6 +634,7 @@ int smblib_get_prop_voltage_wls_output(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_set_prop_dc_reset(struct smb_charger *chg);
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,
+13 −0
Original line number Diff line number Diff line
@@ -280,6 +280,7 @@ enum {
#define HVDCP_EN_BIT				BIT(2)

#define USBIN_OPTIONS_2_CFG_REG			(USBIN_BASE + 0x63)
#define DCD_TIMEOUT_SEL_BIT			BIT(5)
#define FLOAT_OPTIONS_MASK			GENMASK(2, 0)
#define FLOAT_DIS_CHGING_CFG_BIT		BIT(2)
#define SUSPEND_FLOAT_CFG_BIT			BIT(1)
@@ -317,6 +318,12 @@ enum {

#define DCIN_CMD_IL_REG				(DCIN_BASE + 0x40)
#define DCIN_SUSPEND_BIT			BIT(0)
#define DCIN_EN_OVERRIDE_BIT			BIT(1)
#define DCIN_EN_MASK				GENMASK(2, 1)

#define DCIN_CMD_PON_REG			(DCIN_BASE + 0x45)
#define DCIN_PON_BIT				BIT(0)
#define MID_CHG_BIT					BIT(1)

#define DCIN_LOAD_CFG_REG			(DCIN_BASE + 0x65)
#define INPUT_MISS_POLL_EN_BIT			BIT(5)
@@ -461,6 +468,12 @@ enum {
#define DIE_TEMP_UB_BIT				BIT(1)
#define DIE_TEMP_LB_BIT				BIT(0)

#define SKIN_TEMP_STATUS_REG			(MISC_BASE + 0x08)
#define SKIN_TEMP_SHDN_BIT			BIT(3)
#define SKIN_TEMP_RST_BIT			BIT(2)
#define SKIN_TEMP_UB_BIT			BIT(1)
#define SKIN_TEMP_LB_BIT			BIT(0)

#define CONNECTOR_TEMP_STATUS_REG		(MISC_BASE + 0x09)
#define CONNECTOR_TEMP_SHDN_BIT			BIT(3)
#define CONNECTOR_TEMP_RST_BIT			BIT(2)
Loading