summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMulin Chao <mlchao@nuvoton.com>2018-06-07 00:24:18 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-06-28 16:47:37 -0700
commitab38c2f25602f51994d56b22d5ded7c7bfa0beba (patch)
tree162d0611edaf1b36b60d6339d38e8fa2a370c14a
parent024c9b7777281b85f1e691be52ba748611588449 (diff)
downloadchrome-ec-ab38c2f25602f51994d56b22d5ded7c7bfa0beba.tar.gz
npcx: adc: only enable ADC during conversion for power consumption.
For better power consumption in npcx series ec, this CL only turns on ADC module before starting conversion and turns it off after the conversion is done. If ec enters deep sleep when ADC conversion is ongoing, the conveting process is suspended until next time ec wakes up from the deep sleep. Considering the frequency of ADC's source clock is up to 15MHz, it's more efficient to forbid ec enter deep sleep when the conversion is proceeding. (Each conversion time of ADC channel is ~200us based on this condition.) Forbidding ec enter deep sleep should have no harm. BRANCH=none BUG=b:110170824 TEST=No build errors for npcx7 series. The current of AVCC is reduced from 0.4mA to ~0.01mA on yorp if this patch is applied. Change-Id: Ie9226e942eeefaadbca7c17e45f0b9ee9a2364e9 Signed-off-by: Mulin Chao <mlchao@nuvoton.com> Reviewed-on: https://chromium-review.googlesource.com/1090603 Commit-Ready: Jett Rink <jettrink@chromium.org> Reviewed-by: Furquan Shaikh <furquan@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org>
-rw-r--r--chip/npcx/adc.c14
-rw-r--r--include/system.h1
2 files changed, 12 insertions, 3 deletions
diff --git a/chip/npcx/adc.c b/chip/npcx/adc.c
index 1712b889ab..c8336367ae 100644
--- a/chip/npcx/adc.c
+++ b/chip/npcx/adc.c
@@ -15,6 +15,7 @@
#include "gpio.h"
#include "hooks.h"
#include "registers.h"
+#include "system.h"
#include "task.h"
#include "timer.h"
#include "util.h"
@@ -117,6 +118,11 @@ int adc_read_channel(enum adc_channel ch)
mutex_lock(&adc_lock);
+ /* Forbid ec enter deep sleep during ADC conversion is proceeding. */
+ disable_sleep(SLEEP_MASK_ADC);
+ /* Turn on ADC */
+ SET_BIT(NPCX_ADCCNF, NPCX_ADCCNF_ADCEN);
+
if (start_single_and_wait(adc->input_ch, ADC_TIMEOUT_US)) {
chn_data = NPCX_CHNDAT(adc->input_ch);
if ((adc->input_ch ==
@@ -132,6 +138,11 @@ int adc_read_channel(enum adc_channel ch)
value = ADC_READ_ERROR;
}
+ /* Turn off ADC */
+ CLEAR_BIT(NPCX_ADCCNF, NPCX_ADCCNF_ADCEN);
+ /* Allow ec enter deep sleep */
+ enable_sleep(SLEEP_MASK_ADC);
+
mutex_unlock(&adc_lock);
return value;
@@ -178,9 +189,6 @@ static void adc_init(void)
clock_enable_peripheral(CGC_OFFSET_ADC, CGC_ADC_MASK,
CGC_MODE_RUN | CGC_MODE_SLEEP);
- /* Enable ADC */
- SET_BIT(NPCX_ADCCNF, NPCX_ADCCNF_ADCEN);
-
/* Set Core Clock Division Factor in order to obtain the ADC clock */
adc_freq_changed();
diff --git a/include/system.h b/include/system.h
index c40abc7993..ef7c9f5f9b 100644
--- a/include/system.h
+++ b/include/system.h
@@ -427,6 +427,7 @@ enum {
SLEEP_MASK_PHYSICAL_PRESENCE = (1 << 11), /* Physical presence
* detection ongoing */
SLEEP_MASK_PLL = (1 << 12), /* High-speed PLL in-use */
+ SLEEP_MASK_ADC = (1 << 13), /* ADC conversion ongoing */
SLEEP_MASK_FORCE_NO_DSLEEP = (1 << 15), /* Force disable. */