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

Commit 6c584350 authored by Xiaozhe Shi's avatar Xiaozhe Shi
Browse files

hwmon: qpnp-adc: add PM8110 2.0 temperature compensation info



Add in support for PM8110 2.0 temperature compensation. Also, fix a few
bugs in the ADC compensation algorithm where 25C was treated as 2.5C.

Change-Id: Iafa3ceca2b5938432116ecc905dd54b2da7c4b0b
Signed-off-by: default avatarXiaozhe Shi <xiaozhes@codeaurora.org>
parent 275427b2
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -1071,6 +1071,13 @@ int qpnp_adc_get_revid_version(struct device *dev)
		(revid_data->pmic_type == PM8110_V1P0_TYPE) &&
		(revid_data->pmic_subtype == PM8110_V1P0_SUBTYPE))
			return QPNP_REV_ID_8110_1_0;
	else if ((revid_data->rev1 == PM8110_V2P0_REV1) &&
		(revid_data->rev2 == PM8110_V2P0_REV2) &&
		(revid_data->rev3 == PM8110_V2P0_REV3) &&
		(revid_data->rev4 == PM8110_V2P0_REV4) &&
		(revid_data->pmic_type == PM8110_V2P0_TYPE) &&
		(revid_data->pmic_subtype == PM8110_V2P0_SUBTYPE))
			return QPNP_REV_ID_8110_2_0;
	else
		return -EINVAL;
}
+35 −0
Original line number Diff line number Diff line
@@ -355,6 +355,8 @@ static int32_t qpnp_iadc_read_conversion_result(struct qpnp_iadc_chip *iadc,
#define QPNP_COEFF_24					84
#define QPNP_COEFF_25					33
#define QPNP_COEFF_26					22
#define QPNP_COEFF_27					53
#define QPNP_COEFF_28					48

static int32_t qpnp_iadc_comp(int64_t *result, struct qpnp_iadc_chip *iadc,
							int64_t die_temp)
@@ -552,6 +554,39 @@ static int32_t qpnp_iadc_comp(int64_t *result, struct qpnp_iadc_chip *iadc,
			break;
		}
		break;
	case QPNP_REV_ID_8110_2_0:
		die_temp -= 25000;
		/* pm8110 rev 2.0 */
		switch (iadc->iadc_comp.id) {
		case COMP_ID_GF:
			if (!iadc->iadc_comp.ext_rsense) {
				/* internal rsense */
				if (*result < 0) {
					/* charge */
					coeff_a = 0;
					coeff_b = 0;
				} else {
					coeff_a = QPNP_COEFF_27;
					coeff_b = 0;
				}
			}
			break;
		case COMP_ID_SMIC:
		default:
			if (!iadc->iadc_comp.ext_rsense) {
				/* internal rsense */
				if (*result < 0) {
					/* charge */
					coeff_a = 0;
					coeff_b = 0;
				} else {
					coeff_a = QPNP_COEFF_28;
					coeff_b = 0;
				}
			}
			break;
		}
		break;
	default:
	case QPNP_REV_ID_8026_2_0:
		/* pm8026 rev 1.0 */
+82 −17
Original line number Diff line number Diff line
@@ -512,6 +512,16 @@ static int32_t qpnp_vadc_version_check(struct qpnp_vadc_chip *dev)
#define QPNP_VBAT_COEFF_13	102640000
#define QPNP_VBAT_COEFF_14	22220000
#define QPNP_VBAT_COEFF_15	83060000
#define QPNP_VBAT_COEFF_16	2810
#define QPNP_VBAT_COEFF_17	5260
#define QPNP_VBAT_COEFF_18	8027
#define QPNP_VBAT_COEFF_19	2347
#define QPNP_VBAT_COEFF_20	6043
#define QPNP_VBAT_COEFF_21	1914
#define QPNP_VBAT_OFFSET_SMIC	9446
#define QPNP_VBAT_OFFSET_GF	9441
#define QPNP_OCV_OFFSET_SMIC	4596
#define QPNP_OCV_OFFSET_GF	5896

static int32_t qpnp_ocv_comp(int64_t *result,
			struct qpnp_vadc_chip *vadc, int64_t die_temp)
@@ -524,11 +534,15 @@ static int32_t qpnp_ocv_comp(int64_t *result,
	if (version == -EINVAL)
		return 0;

	if (version == QPNP_REV_ID_8110_2_0) {
		if (die_temp < -20000)
			die_temp = -20000;
	} else {
		if (die_temp < 25000)
			return 0;

		if (die_temp > 60000)
			die_temp = 60000;
	}

	switch (version) {
	case QPNP_REV_ID_8941_3_1:
@@ -565,16 +579,40 @@ static int32_t qpnp_ocv_comp(int64_t *result,
	case QPNP_REV_ID_8026_2_1:
		switch (vadc->id) {
		case COMP_ID_TSMC:
			temp_var = ((die_temp - 2500) *
			temp_var = ((die_temp - 25000) *
			(-QPNP_VBAT_COEFF_10));
			break;
		default:
		case COMP_ID_GF:
			temp_var = ((die_temp - 2500) *
			temp_var = ((die_temp - 25000) *
			(-QPNP_VBAT_COEFF_8));
			break;
		}
		break;
	case QPNP_REV_ID_8110_2_0:
		switch (vadc->id) {
		case COMP_ID_SMIC:
			*result -= QPNP_OCV_OFFSET_SMIC;
			if (die_temp < 25000)
				temp_var = QPNP_VBAT_COEFF_18;
			else
				temp_var = QPNP_VBAT_COEFF_19;
			temp_var = (die_temp - 25000) * temp_var;
			break;
		case COMP_ID_TSMC:
			pr_debug("No TSMC Comp Info, exiting\n");
			return 0;
		default:
		case COMP_ID_GF:
			*result -= QPNP_OCV_OFFSET_GF;
			if (die_temp < 25000)
				temp_var = QPNP_VBAT_COEFF_20;
			else
				temp_var = QPNP_VBAT_COEFF_21;
			temp_var = (die_temp - 25000) * temp_var;
			break;
		}
		break;
	default:
		temp_var = 0;
		break;
@@ -603,12 +641,16 @@ static int32_t qpnp_vbat_sns_comp(int64_t *result,
	if (version == -EINVAL)
		return 0;

	if (version == QPNP_REV_ID_8110_2_0) {
		if (die_temp < -20000)
			die_temp = -20000;
	} else {
		if (die_temp < 25000)
			return 0;

		/* min(die_temp_c, 60_degC) */
		if (die_temp > 60000)
			die_temp = 60000;
	}

	switch (version) {
	case QPNP_REV_ID_8941_3_1:
@@ -644,16 +686,34 @@ static int32_t qpnp_vbat_sns_comp(int64_t *result,
	case QPNP_REV_ID_8026_2_1:
		switch (vadc->id) {
		case COMP_ID_TSMC:
			temp_var = ((die_temp - 2500) *
			temp_var = ((die_temp - 25000) *
			(-QPNP_VBAT_COEFF_11));
			break;
		default:
		case COMP_ID_GF:
			temp_var = ((die_temp - 2500) *
			temp_var = ((die_temp - 25000) *
			(-QPNP_VBAT_COEFF_9));
			break;
		}
		break;
	case QPNP_REV_ID_8110_2_0:
		switch (vadc->id) {
		case COMP_ID_SMIC:
			*result -= QPNP_VBAT_OFFSET_SMIC;
			temp_var = ((die_temp - 25000) *
			(QPNP_VBAT_COEFF_17));
			break;
		case COMP_ID_TSMC:
			pr_debug("No TSMC Comp Info, exiting\n");
			return 0;
		default:
		case COMP_ID_GF:
			*result -= QPNP_VBAT_OFFSET_GF;
			temp_var = ((die_temp - 25000) *
			(QPNP_VBAT_COEFF_16));
			break;
		}
		break;
	default:
		temp_var = 0;
		break;
@@ -672,7 +732,7 @@ static int32_t qpnp_vbat_sns_comp(int64_t *result,
}

int32_t qpnp_vbat_sns_comp_result(struct qpnp_vadc_chip *vadc,
						int64_t *result)
					int64_t *result, bool is_pon_ocv)
{
	struct qpnp_vadc_result die_temp_result;
	int rc = 0;
@@ -688,7 +748,12 @@ int32_t qpnp_vbat_sns_comp_result(struct qpnp_vadc_chip *vadc,
		return rc;
	}

	if (is_pon_ocv)
		rc = qpnp_ocv_comp(result, vadc, die_temp_result.physical);
	else
		rc = qpnp_vbat_sns_comp(result, vadc,
				die_temp_result.physical);

	if (rc < 0)
		pr_err("Error with vbat compensation\n");

+6 −6
Original line number Diff line number Diff line
@@ -483,7 +483,7 @@ static int convert_vbatt_uv_to_raw(struct qpnp_bms_chip *chip,
}

static inline int convert_vbatt_raw_to_uv(struct qpnp_bms_chip *chip,
					uint16_t reading)
					uint16_t reading, bool is_pon_ocv)
{
	int64_t uv;
	int rc;
@@ -492,7 +492,7 @@ static inline int convert_vbatt_raw_to_uv(struct qpnp_bms_chip *chip,
	pr_debug("%u raw converted into %lld uv\n", reading, uv);
	uv = adjust_vbatt_reading(chip, uv);
	pr_debug("adjusted into %lld uv\n", uv);
	rc = qpnp_vbat_sns_comp_result(chip->vadc_dev, &uv);
	rc = qpnp_vbat_sns_comp_result(chip->vadc_dev, &uv, is_pon_ocv);
	if (rc)
		pr_debug("could not compensate vbatt\n");
	pr_debug("compensated into %lld uv\n", uv);
@@ -689,7 +689,7 @@ static int calib_vadc(struct qpnp_bms_chip *chip)

static void convert_and_store_ocv(struct qpnp_bms_chip *chip,
				struct raw_soc_params *raw,
				int batt_temp)
				int batt_temp, bool is_pon_ocv)
{
	int rc;

@@ -701,7 +701,7 @@ static void convert_and_store_ocv(struct qpnp_bms_chip *chip,
		pr_err("Vadc reference voltage read failed, rc = %d\n", rc);
	chip->prev_last_good_ocv_raw = raw->last_good_ocv_raw;
	raw->last_good_ocv_uv = convert_vbatt_raw_to_uv(chip,
					raw->last_good_ocv_raw);
					raw->last_good_ocv_raw, is_pon_ocv);
	chip->last_ocv_uv = raw->last_good_ocv_uv;
	chip->last_ocv_temp = batt_temp;
	chip->software_cc_uah = 0;
@@ -1006,7 +1006,7 @@ static int read_soc_params_raw(struct qpnp_bms_chip *chip,
	mutex_unlock(&chip->bms_output_lock);

	if (chip->prev_last_good_ocv_raw == OCV_RAW_UNINITIALIZED) {
		convert_and_store_ocv(chip, raw, batt_temp);
		convert_and_store_ocv(chip, raw, batt_temp, true);
		pr_debug("PON_OCV_UV = %d, cc = %llx\n",
				chip->last_ocv_uv, raw->cc);
		warm_reset = qpnp_pon_is_warm_reset();
@@ -1042,7 +1042,7 @@ static int read_soc_params_raw(struct qpnp_bms_chip *chip,
		pr_debug("EOC Battery full ocv_reading = 0x%x\n",
				chip->ocv_reading_at_100);
	} else if (chip->prev_last_good_ocv_raw != raw->last_good_ocv_raw) {
		convert_and_store_ocv(chip, raw, batt_temp);
		convert_and_store_ocv(chip, raw, batt_temp, false);
		/* forget the old cc value upon ocv */
		chip->last_cc_uah = INT_MIN;
	} else {
+3 −1
Original line number Diff line number Diff line
@@ -1020,6 +1020,7 @@ struct qpnp_adc_amux_properties {
#define QPNP_REV_ID_8026_2_0	3
#define QPNP_REV_ID_8110_1_0	4
#define QPNP_REV_ID_8026_2_1	5
#define QPNP_REV_ID_8110_2_0	6

/* Public API */
#if defined(CONFIG_SENSORS_QPNP_ADC_VOLTAGE)				\
@@ -1376,9 +1377,10 @@ int32_t qpnp_vadc_iadc_sync_complete_request(struct qpnp_vadc_chip *dev,
 * qpnp_vadc_sns_comp_result() - Compensate vbatt readings based on temperature
 * @dev:	Structure device for qpnp vadc
 * @result:	Voltage in uV that needs compensation.
 * @is_pon_ocv: Whether the reading is from a power on OCV or not
 */
int32_t qpnp_vbat_sns_comp_result(struct qpnp_vadc_chip *dev,
						int64_t *result);
					int64_t *result, bool is_pon_ocv);
/**
 * qpnp_adc_get_revid_version() - Obtain the PMIC number and revision.
 * @dev:	Structure device node.