Merge "dev: vadc: Add VADC_USR peripheral driver for PMD9650"
diff --git a/dev/pmic/pm8x41/include/pm_vadc_hc.h b/dev/pmic/pm8x41/include/pm_vadc_hc.h
new file mode 100644
index 0000000..53312cb
--- /dev/null
+++ b/dev/pmic/pm8x41/include/pm_vadc_hc.h
@@ -0,0 +1,234 @@
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PM_VADC_HC_H_
+#define PM_VADC_HC_H_
+
+#include <sys/types.h>
+#include <bits.h>
+
+/* HC_ peripheral */
+#define HC_STATUS1					0x8
+
+#define HC_DATA_HOLD_CTL				0x3f
+#define HC_DATA_HOLD_CTL_FIELD				BIT(1)
+
+#define HC_ADC_DIG_PARAM				0x42
+#define HC_CAL_VAL					BIT(6)
+
+#define HC_CAL_VAL_SHIFT				6
+#define HC_CAL_SEL_MASK					0x30
+#define HC_CAL_SEL_SHIFT				4
+#define HC_DEC_RATIO_SEL				0xc
+#define HC_DEC_RATIO_SHIFT				2
+
+#define HC_FAST_AVG_CTL					0x43
+#define HC_FAST_AVG_SAMPLES_MASK			0xfff
+
+#define HC_ADC_CH_SEL_CTL				0x44
+
+#define HC_DELAY_CTL					0x45
+#define HC_DELAY_CTL_MASK				0xfff
+
+#define HC_EN_CTL1					0x46
+#define HC_ADC_EN					BIT(7)
+
+#define HC_CONV_REQ					0x47
+#define HC_CONV_REQ_START				BIT(7)
+
+#define HC_DATA0					0x50
+#define HC_DATA1					0x51
+
+#define HC_DATA_CHECK_USR				0x8000
+#define HC_CONV_TIME					250
+#define HC_ERR_COUNT					1600
+#define HC_VREF_CODE					0x4000
+
+enum adc_type {
+	PM_VADC_HC = 0,
+	PMI_VADC_HC = 1,
+	VADC_INVALID
+};
+
+struct adc_dev {
+	enum adc_type	adc_type;
+};
+
+enum adc_channel_prediv_type {
+	SCALE_DIV1 = 0,
+	SCALE_DIV3,
+	SCALE_DIV4,
+	SCALE_DIV6,
+	SCALE_DIV20,
+	SCALE_DIV8,
+	SCALE10_DIV81,
+	SCALE_DIV10,
+};
+
+struct adc_pre_scale_ratio {
+	uint8_t		num;
+	uint8_t		den;
+};
+
+enum adc_dig_cal_sel {
+	HC_NO_CAL		= 0,
+	HC_RATIO_CAL,
+	HC_ABS_CAL,
+	HC_CAL_INVALID
+};
+
+enum adc_hc_channel {
+	HC_VREF_GND		= 0,
+	HC_CALIB_VREF_1P25	= 1,
+	HC_CALIB_VREF		= 2,
+	HC_CALIB_VREF_1_DIV_3	= 0x82,
+	HC_VPH_PWR		= 0x83,
+	HC_VBAT_SNS		= 0x84,
+	HC_VCOIN		= 0x85,
+	HC_DIE_TEMP		= 6,
+	HC_CHG_TEMP		= 7,
+	HC_USB_IN		= 8,
+	HC_IREG_FB		= 9,
+	/* External input connection */
+	HC_BAT_THERM		= 0xa,
+	HC_BAT_ID		= 0xb,
+	HC_XO_THERM		= 0xc,
+	HC_AMUX_THM1		= 0xd,
+	HC_AMUX_THM2		= 0xe,
+	HC_AMUX_THM3		= 0xf,
+	HC_AMUX_THM4		= 0x10,
+	HC_AMUX_THM5		= 0x11,
+	HC_AMUX1_GPIO		= 0x12,
+	HC_AMUX2_GPIO		= 0x13,
+	HC_AMUX3_GPIO		= 0x14,
+	HC_AMUX4_GPIO		= 0x15,
+	HC_AMUX5_GPIO		= 0x16,
+	HC_AMUX6_GPIO		= 0x17,
+	HC_AMUX7_GPIO		= 0x18,
+	HC_AMUX8_GPIO		= 0x19,
+	HC_ATEST1		= 0x1a,
+	HC_ATEST2		= 0x1b,
+	HC_ATEST3		= 0x1c,
+	HC_ATEST4		= 0x1d,
+	HC_OFF			= 0xff,
+	/* PU1 is 30K pull up */
+	HC_BAT_THERM_PU1	= 0x2a,
+	HC_BAT_ID_PU1		= 0x2b,
+	HC_XO_THERM_PU1		= 0x2c,
+	HC_AMUX_THM1_PU1	= 0x2d,
+	HC_AMUX_THM2_PU1	= 0x2e,
+	HC_AMUX_THM3_PU1	= 0x2f,
+	HC_AMUX_THM4_PU1	= 0x30,
+	HC_AMUX_THM5_PU1	= 0x31,
+	HC_AMUX1_GPIO_PU1	= 0x32,
+	HC_AMUX2_GPIO_PU1	= 0x33,
+	HC_AMUX3_GPIO_PU1	= 0x34,
+	HC_AMUX4_GPIO_PU1	= 0x35,
+	HC_AMUX5_GPIO_PU1	= 0x36,
+	HC_AMUX6_GPIO_PU1	= 0x37,
+	HC_AMUX7_GPIO_PU1	= 0x38,
+	HC_AMUX8_GPIO_PU1	= 0x39,
+	/* PU2 is 100K pull up */
+	HC_BAT_THERM_PU2	= 0x4a,
+	HC_BAT_ID_PU2		= 0x4b,
+	HC_XO_THERM_PU2		= 0x4c,
+	HC_AMUX_THM1_PU2	= 0x4d,
+	HC_AMUX_THM2_PU2	= 0x4e,
+	HC_AMUX_THM3_PU2	= 0x4f,
+	HC_AMUX_THM4_PU2	= 0x50,
+	HC_AMUX_THM5_PU2	= 0x51,
+	HC_AMUX1_GPIO_PU2	= 0x52,
+	HC_AMUX2_GPIO_PU2	= 0x53,
+	HC_AMUX3_GPIO_PU2	= 0x54,
+	HC_AMUX4_GPIO_PU2	= 0x55,
+	HC_AMUX5_GPIO_PU2	= 0x56,
+	HC_AMUX6_GPIO_PU2	= 0x57,
+	HC_AMUX7_GPIO_PU2	= 0x58,
+	HC_AMUX8_GPIO_PU2	= 0x59,
+	/* PU3 is 400K pull up */
+	HC_BAT_THERM_PU3	= 0x6a,
+	HC_BAT_ID_PU3		= 0x6b,
+	HC_XO_THERM_PU3		= 0x6c,
+	HC_AMUX_THM1_PU3	= 0x6d,
+	HC_AMUX_THM2_PU3	= 0x6e,
+	HC_AMUX_THM3_PU3	= 0x6f,
+	HC_AMUX_THM4_PU3	= 0x70,
+	HC_AMUX_THM5_PU3	= 0x71,
+	HC_AMUX1_GPIO_PU3	= 0x72,
+	HC_AMUX2_GPIO_PU3	= 0x73,
+	HC_AMUX3_GPIO_PU3	= 0x74,
+	HC_AMUX4_GPIO_PU3	= 0x75,
+	HC_AMUX5_GPIO_PU3	= 0x76,
+	HC_AMUX6_GPIO_PU3	= 0x77,
+	HC_AMUX7_GPIO_PU3	= 0x78,
+	HC_AMUX8_GPIO_PU3	= 0x79,
+	/* External input connection with 1/3 div */
+	HC_AMUX1_GPIO_DIV_3	= 0x92,
+	HC_AMUX2_GPIO_DIV_3	= 0x93,
+	HC_AMUX3_GPIO_DIV_3	= 0x94,
+	HC_AMUX4_GPIO_DIV_3	= 0x95,
+	HC_AMUX5_GPIO_DIV_3	= 0x96,
+	HC_AMUX6_GPIO_DIV_3	= 0x97,
+	HC_AMUX7_GPIO_DIV_3	= 0x98,
+	HC_AMUX8_GPIO_DIV_3	= 0x99,
+	HC_ATEST1_DIV_3		= 0x9a,
+	HC_ATEST2_DIV_3		= 0x9b,
+	HC_ATEST3_DIV_3		= 0x9c,
+	HC_ATEST4_DIV_3		= 0x9d,
+	HC_INVALID		= 0xffff
+};
+
+enum adc_usr_delay_ctl {
+	HC_HW_SETTLE_DELAY_0US = 0,
+	HC_HW_SETTLE_DELAY_100US,
+	HC_HW_SETTLE_DELAY_200US,
+	HC_HW_SETTLE_DELAY_300US,
+	HC_HW_SETTLE_DELAY_400US,
+	HC_HW_SETTLE_DELAY_500US,
+	HC_HW_SETTLE_DELAY_600US,
+	HC_HW_SETTLE_DELAY_700US,
+	HC_HW_SETTLE_DELAY_800US,
+	HC_HW_SETTLE_DELAY_900US,
+	HC_HW_SETTLE_DELAY_1MS,
+	HC_HW_SETTLE_DELAY_2MS,
+	HC_HW_SETTLE_DELAY_4MS,
+	HC_HW_SETTLE_DELAY_6MS,
+	HC_HW_SETTLE_DELAY_8MS,
+	HC_HW_SETTLE_DELAY_10MS,
+	HC_HW_SETTLE_DELAY_INVALID
+};
+
+struct adc_result {
+	uint16_t	adc_code;
+	int64_t		physical;
+};
+
+int vadc_hc_read(struct adc_dev *dev, enum adc_hc_channel channel,
+					struct adc_result *result);
+
+#endif /* _PM_VADC_HC_H_ */
diff --git a/dev/pmic/pm8x41/pm_vadc_hc.c b/dev/pmic/pm8x41/pm_vadc_hc.c
new file mode 100644
index 0000000..fdf26ab
--- /dev/null
+++ b/dev/pmic/pm8x41/pm_vadc_hc.c
@@ -0,0 +1,312 @@
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <debug.h>
+#include <spmi.h>
+#include <platform/timer.h>
+#include <pm_vadc_hc.h>
+#include <pm8x41_hw.h>
+
+static const struct adc_pre_scale_ratio vadc_hc_scale[] = {
+	[SCALE_DIV1]	= {1,	1},
+	[SCALE_DIV3]	= {1,	3},
+	[SCALE_DIV4]	= {1,	4},
+	[SCALE_DIV6]	= {1,	6},
+	[SCALE_DIV20]	= {1,	20},
+	[SCALE_DIV8]	= {1,	8},
+	[SCALE10_DIV81]	= {10,	81},
+	[SCALE_DIV10]	= {1,	10}
+};
+
+struct vadc_hc_periph_cfg {
+	/* Peripheral base address */
+	uint32_t			base;
+	/* vdd_vref in millivolts */
+	uint32_t			vdd_vref;
+	/* ADC reference code used in post scaling calculation */
+	uint32_t			vref_code;
+	/* PM VADC /PMI VADC */
+	enum adc_type			adc_type;
+};
+
+struct vadc_hc_channel_cfg {
+	/* Calibration type for the channel - absolute/ratiometric */
+	enum adc_dig_cal_sel		cal_sel;
+	/* VADC channel number */
+	enum adc_hc_channel		channel;
+	/* Hardware settling delay for the channel */
+	enum adc_usr_delay_ctl		hw_settle;
+	/*
+	 * Pre scale ratio for the channel before ADC is measured.
+	 * This is used during scaling the code to physical units by
+	 * applying the respective pre-scale value.
+	 */
+	struct adc_pre_scale_ratio	pre_scale;
+	/*
+	 * Scaling function used for converting the adc code to
+	 * physical units based on channel properties
+	 */
+	int (*scale)(struct vadc_hc_periph_cfg *adc_cfg,
+			uint16_t adc_code, struct adc_pre_scale_ratio *ratio,
+					int64_t *result);
+};
+
+static struct vadc_hc_periph_cfg vadc_pdata[] = {
+	{
+		.base =		0x3100,
+		.vdd_vref =	1875,
+		.vref_code =	0x4000,
+		.adc_type =	PM_VADC_HC
+	},
+	{
+		.base =		0x23100,
+		.vdd_vref =	1875,
+		.vref_code =	0x4000,
+		.adc_type =	PMI_VADC_HC
+	},
+};
+
+static int scale_default_voltage(struct vadc_hc_periph_cfg *adc_cfg,
+			uint16_t adc_code,
+			struct adc_pre_scale_ratio *ratio,
+			int64_t *result);
+
+/*
+ * This is an example of a container channel properties thats expected
+ * by the ADC driver. Clients can add channels based on the
+ * VADC channels supported by the target.
+ */
+static struct vadc_hc_channel_cfg channel_pdata[] = {
+	{
+		/* 1.25V reference channel */
+		HC_ABS_CAL,
+		HC_CALIB_VREF_1P25,
+		HC_HW_SETTLE_DELAY_0US,
+		{1, 1},
+		scale_default_voltage
+	},
+	{
+		/* vph_pwr channel */
+		HC_ABS_CAL,
+		HC_VPH_PWR,
+		HC_HW_SETTLE_DELAY_0US,
+		{1, 3},
+		scale_default_voltage
+	},
+};
+
+static void vadc_hc_reg_write(struct vadc_hc_periph_cfg *adc_cfg,
+					uint8_t offset, uint8_t val)
+{
+	REG_WRITE((adc_cfg->base + offset), val);
+}
+
+static void vadc_hc_reg_read(struct vadc_hc_periph_cfg *adc_cfg,
+					uint8_t offset, uint8_t *val)
+{
+	*val = REG_READ((adc_cfg->base + offset));
+}
+
+static int scale_default_voltage(struct vadc_hc_periph_cfg *adc_cfg,
+			uint16_t adc_code,
+			struct adc_pre_scale_ratio *ratio,
+			int64_t *result)
+{
+	int64_t voltage = 0, den = 0;
+
+	if (!ratio)
+		return -1;
+
+	voltage = (int64_t) adc_code;
+	voltage *= (int64_t) adc_cfg->vdd_vref * 1000;
+	den = (int64_t) adc_cfg->vref_code;
+	*result = voltage / den;
+	*result *= ratio->den;
+	*result = *result / ratio->num;
+
+	return 0;
+}
+
+static int vadc_hc_read_result(struct vadc_hc_periph_cfg *adc_cfg,
+							uint16_t *data)
+{
+	uint8_t code_lsb = 0, code_msb = 0, hold_bit = 0, en = 0;
+
+	/* Set hold bit */
+	vadc_hc_reg_read(adc_cfg, HC_DATA_HOLD_CTL, &hold_bit);
+	hold_bit |= HC_DATA_HOLD_CTL_FIELD;
+
+	/* Read LSB/MSB */
+	vadc_hc_reg_read(adc_cfg, HC_DATA0, &code_lsb);
+	vadc_hc_reg_read(adc_cfg, HC_DATA1, &code_msb);
+	*data = (code_msb << 8) | code_lsb;
+	if (*data == HC_DATA_CHECK_USR) {
+		dprintf(SPEW, "Invalid data :0x%x\n", *data);
+		return -1;
+	}
+
+	/* Disable peripheral */
+	vadc_hc_reg_write(adc_cfg, HC_EN_CTL1, en);
+
+	/* De-assert hold bit */
+	hold_bit &= ~HC_DATA_HOLD_CTL_FIELD;
+	vadc_hc_reg_read(adc_cfg, HC_DATA_HOLD_CTL, &hold_bit);
+
+	return 0;
+}
+
+static int32_t vadc_hc_check_completion(struct vadc_hc_periph_cfg *adc_cfg)
+{
+	int32_t i = 0;
+	uint8_t status_bit = 0;
+
+	for (i = 0; i < HC_ERR_COUNT; i++) {
+		vadc_hc_reg_read(adc_cfg, HC_STATUS1, &status_bit);
+		if (status_bit == 0x1)
+			return 0;
+
+		udelay(HC_CONV_TIME);
+	};
+
+	dprintf(SPEW, "Status bit not set with 0x%x\n", status_bit);
+
+	return -1;
+}
+
+static void vadc_hc_configure(struct vadc_hc_periph_cfg *adc_cfg,
+				struct vadc_hc_channel_cfg *ch_cfg)
+{
+	uint8_t cal = 0;
+
+	/* Configure calibration select */
+	vadc_hc_reg_read(adc_cfg, HC_ADC_DIG_PARAM, &cal);
+	cal &= ~HC_CAL_SEL_MASK;
+	cal = cal | (ch_cfg->cal_sel << HC_CAL_SEL_SHIFT);
+	vadc_hc_reg_write(adc_cfg, HC_ADC_DIG_PARAM, cal);
+
+	/* Configure channel */
+	vadc_hc_reg_write(adc_cfg, HC_ADC_CH_SEL_CTL, ch_cfg->channel);
+
+	/* HW settle delay */
+	vadc_hc_reg_write(adc_cfg, HC_DELAY_CTL, ch_cfg->hw_settle);
+
+	/* Enable ADC */
+	vadc_hc_reg_write(adc_cfg, HC_EN_CTL1, HC_ADC_EN);
+
+	/* Request conversion */
+	vadc_hc_reg_write(adc_cfg, HC_CONV_REQ, HC_CONV_REQ_START);
+}
+
+static int vadc_check_channel_type(enum adc_hc_channel channel, int32_t *idx)
+{
+	uint32_t i = 0;
+
+	for (i = 0; i < ARRAY_SIZE(channel_pdata); i++) {
+		if (channel_pdata[i].channel == channel) {
+			*idx = i;
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(channel_pdata))
+		return -1;
+
+	return 0;
+}
+
+static int vadc_check_adc_type(struct adc_dev *dev)
+{
+	uint32_t i = 0;
+
+	if (dev->adc_type >= VADC_INVALID) {
+		dprintf(SPEW, "Invalid VADC_TYPE\n");
+		return -1;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(vadc_pdata); i++)
+		if (vadc_pdata[i].adc_type == dev->adc_type)
+			break;
+
+	if (i == ARRAY_SIZE(vadc_pdata))
+		return -1;
+
+	return 0;
+}
+
+int vadc_hc_read(struct adc_dev *dev, enum adc_hc_channel channel,
+					struct adc_result *result)
+{
+	struct vadc_hc_periph_cfg *adc_cfg;
+	struct vadc_hc_channel_cfg *chan_cfg;
+	int32_t rc = 0, idx = 0;
+	uint16_t adc_code;
+	int64_t converted_value;
+
+	if (!dev || channel >= HC_INVALID || !result) {
+		dprintf(SPEW, "Invalid params\n");
+		return -1;
+	}
+
+	rc = vadc_check_adc_type(dev);
+	if (rc) {
+		dprintf(SPEW, "Invalid adc_type params %d\n", dev->adc_type);
+		return -1;
+	}
+	adc_cfg = &vadc_pdata[dev->adc_type];
+
+	rc = vadc_check_channel_type(channel, &idx);
+	if (rc) {
+		dprintf(SPEW, "Channel pdata not present 0x%x\n", channel);
+		return -1;
+	}
+	chan_cfg = &channel_pdata[idx];
+
+	/* Configure ADC for the channel */
+	vadc_hc_configure(adc_cfg, chan_cfg);
+
+	/* Check completion */
+	rc = vadc_hc_check_completion(adc_cfg);
+	if (rc)
+		return -1;
+
+	/* Read ADC code */
+	rc = vadc_hc_read_result(adc_cfg, &adc_code);
+	if (rc)
+		return -1;
+	result->adc_code = adc_code;
+
+	dprintf(INFO, "adc_code:0x%x\n", adc_code);
+
+	/* Scale to physical units */
+	chan_cfg->scale(adc_cfg, adc_code, &chan_cfg->pre_scale,
+						&converted_value);
+	result->physical = converted_value;
+	dprintf(INFO, "converted value:%lld\n", converted_value);
+
+	return 0;
+}
diff --git a/dev/pmic/pm8x41/rules.mk b/dev/pmic/pm8x41/rules.mk
index a857013..19d15be 100644
--- a/dev/pmic/pm8x41/rules.mk
+++ b/dev/pmic/pm8x41/rules.mk
@@ -16,3 +16,8 @@
 OBJS += \
 	$(LOCAL_DIR)/pm_pwm.o
 endif
+
+ifeq ($(ENABLE_VADC_HC_SUPPORT),true)
+OBJS += \
+	$(LOCAL_DIR)/pm_vadc_hc.o
+endif
diff --git a/project/mdm9640.mk b/project/mdm9640.mk
index 2c81541..d72ee16 100644
--- a/project/mdm9640.mk
+++ b/project/mdm9640.mk
@@ -17,6 +17,7 @@
 ENABLE_USB30_SUPPORT := 1
 ENABLE_SDHCI_SUPPORT := 1
 ENABLE_BOOT_CONFIG_SUPPORT := 1
+ENABLE_VADC_HC_SUPPORT := true
 
 MODULES += app/aboot