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>
This commit is contained in:
Siddartha Mohanadoss 2012-08-14 15:15:42 -07:00 committed by Iliyan Malchev
parent d471a93ec3
commit 73eebbf41a

View file

@ -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 pm8xxx_adc {
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 @@ static int32_t pm8xxx_adc_patherm_power(bool on)
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 @@ static int __devexit pm8xxx_adc_teardown(struct platform_device *pdev)
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 @@ static int __devinit pm8xxx_adc_probe(struct platform_device *pdev)
}
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);