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

Commit e17597ed authored by Siddartha Mohanadoss's avatar Siddartha Mohanadoss
Browse files

hwmon: qpnp-adc-current: Add temperature compensation



Add temperature compensation parameters for PM8026 2.1.
Compensate the vbatt voltage for temperature variance above
25degC. Add similar compensation for current compensation.

Also update using the revid api's to check for PMIC revision
instead of using peripheral revision registers. Using
revid PMIC api's makes it easy to follow on what PMIC versions
are the temperature compensation being applied to. Depending
on VADC/IADC revision registers alone may not suffice since
there is no correlation between the individual peripheral
revision and the PMIC number. You could have the same
VADC revision on different PMIC's and to avoid such a scenario
use the PMIC revid.

Change-Id: I90adb1130b2e2461f762df774ddcd018e806cf78
Signed-off-by: default avatarSiddartha Mohanadoss <smohanad@codeaurora.org>
parent 4a149ed1
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -21,6 +21,9 @@ Optional properties:
- qcom,rsense : Use this property when external rsense should be used
		for current calculation and specify the units in nano-ohms.
- qcom,iadc-poll-eoc: Use polling instead of interrupts for End of Conversion completion.
- qcom,pmic-revid : Phandle pointing to the revision peripheral node. Use it to query the
		    PMIC type and revision for applying the appropriate temperature
		    compensation parameters.

Channel node
NOTE: Atleast one Channel node is required.
+3 −0
Original line number Diff line number Diff line
@@ -22,6 +22,9 @@ NOTE: Atleast one Channel node is required.

Optional properties:
- qcom,vadc-poll-eoc: Use polling instead of interrupts for End of Conversion completion.
- qcom,pmic-revid : Phandle pointing to the revision peripheral node. Use it to query the
		    PMIC type and revision for applying the appropriate temperature
		    compensation parameters.

Client required property:
- qcom,<consumer name>-vadc : The phandle to the corresponding vadc device.
+58 −0
Original line number Diff line number Diff line
@@ -913,6 +913,64 @@ int32_t qpnp_vadc_check_result(int32_t *data)
}
EXPORT_SYMBOL(qpnp_vadc_check_result);

int qpnp_adc_get_revid_version(struct device *dev)
{
	struct pmic_revid_data *revid_data;
	struct device_node *revid_dev_node;

	revid_dev_node = of_parse_phandle(dev->of_node,
						"qcom,pmic-revid", 0);
	if (!revid_dev_node) {
		pr_debug("Missing qcom,pmic-revid property\n");
		return -EINVAL;
	}

	revid_data = get_revid_data(revid_dev_node);
	if (IS_ERR(revid_data)) {
		pr_err("revid error rc = %ld\n", PTR_ERR(revid_data));
		return -EINVAL;
	}

	if ((revid_data->rev1 == PM8941_V3P1_REV1) &&
		(revid_data->rev2 == PM8941_V3P1_REV2) &&
		(revid_data->rev3 == PM8941_V3P1_REV3) &&
		(revid_data->rev4 == PM8941_V3P1_REV4) &&
		(revid_data->pmic_type == PM8941_V3P1_TYPE) &&
		(revid_data->pmic_subtype == PM8941_V3P1_SUBTYPE))
			return QPNP_REV_ID_8941_3_1;
	else if ((revid_data->rev1 == PM8226_V2P1_REV1) &&
		(revid_data->rev2 == PM8226_V2P1_REV2) &&
		(revid_data->rev3 == PM8226_V2P1_REV3) &&
		(revid_data->rev4 == PM8226_V2P1_REV4) &&
		(revid_data->pmic_type == PM8226_V2P1_TYPE) &&
		(revid_data->pmic_subtype == PM8226_V2P1_SUBTYPE))
			return QPNP_REV_ID_8026_2_1;
	else if ((revid_data->rev1 == PM8226_V2P0_REV1) &&
		(revid_data->rev2 == PM8226_V2P0_REV2) &&
		(revid_data->rev3 == PM8226_V2P0_REV3) &&
		(revid_data->rev4 == PM8226_V2P0_REV4) &&
		(revid_data->pmic_type == PM8226_V2P0_TYPE) &&
		(revid_data->pmic_subtype == PM8226_V2P0_SUBTYPE))
			return QPNP_REV_ID_8026_2_0;
	else if ((revid_data->rev1 == PM8226_V1P0_REV1) &&
		(revid_data->rev2 == PM8226_V1P0_REV2) &&
		(revid_data->rev3 == PM8226_V1P0_REV3) &&
		(revid_data->rev4 == PM8226_V1P0_REV4) &&
		(revid_data->pmic_type == PM8226_V1P0_TYPE) &&
		(revid_data->pmic_subtype == PM8226_V1P0_SUBTYPE))
			return QPNP_REV_ID_8026_1_0;
	else if ((revid_data->rev1 == PM8110_V1P0_REV1) &&
		(revid_data->rev2 == PM8110_V1P0_REV2) &&
		(revid_data->rev3 == PM8110_V1P0_REV3) &&
		(revid_data->rev4 == PM8110_V1P0_REV4) &&
		(revid_data->pmic_type == PM8110_V1P0_TYPE) &&
		(revid_data->pmic_subtype == PM8110_V1P0_SUBTYPE))
			return QPNP_REV_ID_8110_1_0;
	else
		return -EINVAL;
}
EXPORT_SYMBOL(qpnp_adc_get_revid_version);

int32_t qpnp_adc_get_devicetree_data(struct spmi_device *spmi,
			struct qpnp_adc_drv *adc_qpnp)
{
+61 −48
Original line number Diff line number Diff line
@@ -325,48 +325,8 @@ static int32_t qpnp_iadc_read_conversion_result(struct qpnp_iadc_chip *iadc,
	return 0;
}

#define QPNP_IADC_PM8941_3_1_REV2	3
#define QPNP_IADC_PM8941_3_1_REV3	2
#define QPNP_IADC_PM8026_1_REV2		1
#define QPNP_IADC_PM8026_1_REV3		2
#define QPNP_IADC_PM8026_2_REV2	4
#define QPNP_IADC_PM8026_2_REV3	2
#define QPNP_IADC_PM8110_1_REV2		2
#define QPNP_IADC_PM8110_1_REV3		2

#define QPNP_IADC_REV_ID_8941_3_1	1
#define QPNP_IADC_REV_ID_8026_1_0	2
#define QPNP_IADC_REV_ID_8026_2_0	3
#define QPNP_IADC_REV_ID_8110_1_0	4

static void qpnp_temp_comp_version_check(struct qpnp_iadc_chip *iadc,
						int32_t *version)
{
	if ((iadc->iadc_comp.revision_dig_major ==
			QPNP_IADC_PM8941_3_1_REV2) &&
			(iadc->iadc_comp.revision_ana_minor ==
			QPNP_IADC_PM8941_3_1_REV3))
		*version = QPNP_IADC_REV_ID_8941_3_1;
	else if ((iadc->iadc_comp.revision_dig_major ==
			QPNP_IADC_PM8026_1_REV2) &&
			(iadc->iadc_comp.revision_ana_minor ==
			QPNP_IADC_PM8026_1_REV3))
		*version = QPNP_IADC_REV_ID_8026_1_0;
	else if ((iadc->iadc_comp.revision_dig_major ==
			QPNP_IADC_PM8026_2_REV2) &&
			(iadc->iadc_comp.revision_ana_minor ==
			QPNP_IADC_PM8026_2_REV3))
		*version = QPNP_IADC_REV_ID_8026_2_0;
	else if ((iadc->iadc_comp.revision_dig_major ==
			QPNP_IADC_PM8110_1_REV2) &&
			(iadc->iadc_comp.revision_ana_minor ==
			QPNP_IADC_PM8110_1_REV3))
		*version = QPNP_IADC_REV_ID_8110_1_0;
	else
		*version = -EINVAL;

	return;
}

#define QPNP_COEFF_1					969000
#define QPNP_COEFF_2					32
@@ -393,15 +353,17 @@ static void qpnp_temp_comp_version_check(struct qpnp_iadc_chip *iadc,
#define QPNP_COEFF_22					5000000
#define QPNP_COEFF_23					3722500
#define QPNP_COEFF_24					84
#define QPNP_COEFF_25					33
#define QPNP_COEFF_26					22

static int32_t qpnp_iadc_comp(int64_t *result, struct qpnp_iadc_chip *iadc,
							int64_t die_temp)
{
	int64_t temp_var = 0, sys_gain_coeff = 0, old;
	int32_t coeff_a = 0, coeff_b = 0;
	int32_t version;
	int version = 0;

	qpnp_temp_comp_version_check(iadc, &version);
	version = qpnp_adc_get_revid_version(iadc->dev);
	if (version == -EINVAL)
		return 0;

@@ -416,7 +378,7 @@ static int32_t qpnp_iadc_comp(int64_t *result, struct qpnp_iadc_chip *iadc,
				iadc->iadc_comp.sys_gain;

	switch (version) {
	case QPNP_IADC_REV_ID_8941_3_1:
	case QPNP_REV_ID_8941_3_1:
		switch (iadc->iadc_comp.id) {
		case COMP_ID_GF:
			if (!iadc->iadc_comp.ext_rsense) {
@@ -455,7 +417,58 @@ static int32_t qpnp_iadc_comp(int64_t *result, struct qpnp_iadc_chip *iadc,
			break;
		}
		break;
	case QPNP_IADC_REV_ID_8026_1_0:
	case QPNP_REV_ID_8026_2_1:
		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_25;
					coeff_b = 0;
				}
			} else {
				if (*result < 0) {
					/* charge */
					coeff_a = 0;
					coeff_b = 0;
				} else {
					/* discharge */
					coeff_a = 0;
					coeff_b = 0;
				}
			}
			break;
		case COMP_ID_TSMC:
		default:
			if (!iadc->iadc_comp.ext_rsense) {
				/* internal rsense */
				if (*result < 0) {
					/* charge */
					coeff_a = 0;
					coeff_b = 0;
				} else {
					coeff_a = QPNP_COEFF_26;
					coeff_b = 0;
				}
			} else {
				if (*result < 0) {
					/* charge */
					coeff_a = 0;
					coeff_b = 0;
				} else {
					/* discharge */
					coeff_a = 0;
					coeff_b = 0;
				}
			}
			break;
		}
		break;
	case QPNP_REV_ID_8026_1_0:
		/* pm8026 rev 1.0 */
		switch (iadc->iadc_comp.id) {
		case COMP_ID_GF:
@@ -507,7 +520,7 @@ static int32_t qpnp_iadc_comp(int64_t *result, struct qpnp_iadc_chip *iadc,
			break;
		}
		break;
	case QPNP_IADC_REV_ID_8110_1_0:
	case QPNP_REV_ID_8110_1_0:
		/* pm8110 rev 1.0 */
		switch (iadc->iadc_comp.id) {
		case COMP_ID_GF:
@@ -540,7 +553,7 @@ static int32_t qpnp_iadc_comp(int64_t *result, struct qpnp_iadc_chip *iadc,
		}
		break;
	default:
	case QPNP_IADC_REV_ID_8026_2_0:
	case QPNP_REV_ID_8026_2_0:
		/* pm8026 rev 1.0 */
		coeff_a = 0;
		coeff_b = 0;
+12 −32
Original line number Diff line number Diff line
@@ -512,36 +512,14 @@ static int32_t qpnp_vadc_version_check(struct qpnp_vadc_chip *dev)
#define QPNP_VBAT_COEFF_14	22220000
#define QPNP_VBAT_COEFF_15	83060000

#define QPNP_VADC_REV_ID_8941_3_1	1
#define QPNP_VADC_REV_ID_8026_1_0	2
#define QPNP_VADC_REV_ID_8026_2_0	3

static void qpnp_temp_comp_version_check(struct qpnp_vadc_chip *vadc,
							int32_t *version)
{
	if (vadc->revision_dig_major == 3 &&
			vadc->revision_ana_minor == 2)
		*version = QPNP_VADC_REV_ID_8941_3_1;
	else if (vadc->revision_dig_major == 1 &&
			vadc->revision_ana_minor == 2)
		*version = QPNP_VADC_REV_ID_8026_1_0;
	else if (vadc->revision_dig_major == 2 &&
			vadc->revision_ana_minor == 2)
		*version = QPNP_VADC_REV_ID_8026_2_0;
	else
		*version = -EINVAL;

	return;
}

static int32_t qpnp_ocv_comp(int64_t *result,
			struct qpnp_vadc_chip *vadc, int64_t die_temp)
{
	int64_t temp_var = 0;
	int64_t old = *result;
	int32_t version;
	int version;

	qpnp_temp_comp_version_check(vadc, &version);
	version = qpnp_adc_get_revid_version(vadc->dev);
	if (version == -EINVAL)
		return 0;

@@ -552,7 +530,7 @@ static int32_t qpnp_ocv_comp(int64_t *result,
		die_temp = 60000;

	switch (version) {
	case QPNP_VADC_REV_ID_8941_3_1:
	case QPNP_REV_ID_8941_3_1:
		switch (vadc->id) {
		case COMP_ID_TSMC:
			temp_var = (((die_temp *
@@ -567,7 +545,7 @@ static int32_t qpnp_ocv_comp(int64_t *result,
			break;
		}
		break;
	case QPNP_VADC_REV_ID_8026_1_0:
	case QPNP_REV_ID_8026_1_0:
		switch (vadc->id) {
		case COMP_ID_TSMC:
			temp_var = (((die_temp *
@@ -582,7 +560,8 @@ static int32_t qpnp_ocv_comp(int64_t *result,
			break;
		}
		break;
	case QPNP_VADC_REV_ID_8026_2_0:
	case QPNP_REV_ID_8026_2_0:
	case QPNP_REV_ID_8026_2_1:
		switch (vadc->id) {
		case COMP_ID_TSMC:
			temp_var = ((die_temp - 2500) *
@@ -617,9 +596,9 @@ static int32_t qpnp_vbat_sns_comp(int64_t *result,
{
	int64_t temp_var = 0;
	int64_t old = *result;
	int32_t version;
	int version;

	qpnp_temp_comp_version_check(vadc, &version);
	version = qpnp_adc_get_revid_version(vadc->dev);
	if (version == -EINVAL)
		return 0;

@@ -631,7 +610,7 @@ static int32_t qpnp_vbat_sns_comp(int64_t *result,
		die_temp = 60000;

	switch (version) {
	case QPNP_VADC_REV_ID_8941_3_1:
	case QPNP_REV_ID_8941_3_1:
		switch (vadc->id) {
		case COMP_ID_TSMC:
			temp_var = (die_temp *
@@ -645,7 +624,7 @@ static int32_t qpnp_vbat_sns_comp(int64_t *result,
			break;
		}
		break;
	case QPNP_VADC_REV_ID_8026_1_0:
	case QPNP_REV_ID_8026_1_0:
		switch (vadc->id) {
		case COMP_ID_TSMC:
			temp_var = (((die_temp *
@@ -660,7 +639,8 @@ static int32_t qpnp_vbat_sns_comp(int64_t *result,
			break;
		}
		break;
	case QPNP_VADC_REV_ID_8026_2_0:
	case QPNP_REV_ID_8026_2_0:
	case QPNP_REV_ID_8026_2_1:
		switch (vadc->id) {
		case COMP_ID_TSMC:
			temp_var = ((die_temp - 2500) *
Loading