hwmon: pm8xxx-adc: Vote for a PMIC clock buffer.:
Incorrect PMIC_THERM/XO_THERM readings are seen when
the XO clock is disabled.
The internal PMIC therm relies on the PMIC band gap
reference which in turn is enabled when any of the
PMIC clock buffers are enabled. The XO_THERM relies
on the VREF_XO as its reference source which gets
enabled when any of the PMIC clock buffers are
switched on. Therefore vote for a clock buffer when
a PMIC_THERM/XO_THERM is requested.
CRs-Fixed: 392602
Signed-off-by: Siddartha Mohanadoss <smohanad@codeaurora.org>
(cherry picked from commit f9dfe1b7b70b634422fbbbf65756aa997536bd33)
Change-Id: I09e132dbc4e635b96cd08ece245a766d68ed27b4
Signed-off-by: Sridhar Gujje <sgujje@codeaurora.org>
Conflicts:
drivers/hwmon/pm8xxx-adc.c
Signed-off-by: Sridhar Gujje <sgujje@codeaurora.org>
Signed-off-by: Sivasri Kumar Vanka <sivasri@codeaurora.org>
(cherry picked from commit 8ab75c713cef66317f9507b35cc08a5d7b49ae44)
Conflicts:
drivers/hwmon/pm8xxx-adc.c
Signed-off-by: Sridhar Gujje <sgujje@codeaurora.org>
diff --git a/drivers/hwmon/pm8xxx-adc.c b/drivers/hwmon/pm8xxx-adc.c
index ad19ea0..3633332 100644
--- a/drivers/hwmon/pm8xxx-adc.c
+++ b/drivers/hwmon/pm8xxx-adc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -31,6 +31,7 @@
#include <linux/mfd/pm8xxx/core.h>
#include <linux/regulator/consumer.h>
#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
+#include <mach/msm_xo.h>
/* User Bank register set */
#define PM8XXX_ADC_ARB_USRP_CNTRL1 0x197
@@ -141,6 +142,7 @@
struct work_struct cool_work;
uint32_t mpp_base;
struct device *hwmon;
+ struct msm_xo_voter *adc_voter;
int msm_suspend_check;
struct pm8xxx_adc_amux_properties *conv;
struct pm8xxx_adc_arb_btm_param batt;
@@ -290,14 +292,34 @@
return rc;
}
+static int32_t pm8xxx_adc_xo_vote(bool on)
+{
+ struct pm8xxx_adc *adc_pmic = pmic_adc;
+
+ if (on)
+ msm_xo_mode_vote(adc_pmic->adc_voter, MSM_XO_MODE_ON);
+ else
+ msm_xo_mode_vote(adc_pmic->adc_voter, MSM_XO_MODE_OFF);
+
+ return 0;
+}
+
static int32_t pm8xxx_adc_channel_power_enable(uint32_t channel,
bool power_cntrl)
{
int rc = 0;
- switch (channel)
+ switch (channel) {
case ADC_MPP_1_AMUX8:
rc = pm8xxx_adc_patherm_power(power_cntrl);
+ break;
+ case CHANNEL_DIE_TEMP:
+ case CHANNEL_MUXOFF:
+ rc = pm8xxx_adc_xo_vote(power_cntrl);
+ break;
+ default:
+ break;
+ }
return rc;
}
@@ -1147,6 +1169,7 @@
struct pm8xxx_adc *adc_pmic = pmic_adc;
int i;
+ msm_xo_put(adc_pmic->adc_voter);
platform_set_drvdata(pdev, NULL);
pmic_adc = NULL;
if (!pa_therm) {
@@ -1265,6 +1288,14 @@
}
adc_pmic->hwmon = hwmon_device_register(adc_pmic->dev);
+ if (adc_pmic->adc_voter == NULL) {
+ adc_pmic->adc_voter = msm_xo_get(MSM_XO_TCXO_D0, "pmic_xoadc");
+ if (IS_ERR(adc_pmic->adc_voter)) {
+ dev_err(&pdev->dev, "Failed to get XO vote\n");
+ return PTR_ERR(adc_pmic->adc_voter);
+ }
+ }
+
pa_therm = regulator_get(adc_pmic->dev, "pa_therm");
if (IS_ERR(pa_therm)) {
rc = PTR_ERR(pa_therm);