summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMulin Chao <mlchao@nuvoton.com>2016-08-07 05:42:17 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-08-10 15:30:47 -0700
commit0b6a09548825d55dd960180b8bba9fbc2705c962 (patch)
tree41b1a17ea33ab6c505f9dced1a1e98df3ba2b207
parent62af706a02f2b9f59a1f9820b130da905298a8bd (diff)
downloadchrome-ec-0b6a09548825d55dd960180b8bba9fbc2705c962.tar.gz
npcx: adc: Properly wait for conversion interrupt
Certain tasks (eg. chipset) may be woken directly by other tasks / unrelated interrupts. Add an explicit wake event for ADC conversion done so that we're not mistakenly woken. BUG=chrome-os-partner:54971 BRANCH=None TEST=Manual on kevin rev5, run "reboot ap-off" then "sysjump rw", verify console isn't spammed with GPIO warning message due to ADC failure to read board version. Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Change-Id: I5477e11c2b434e4b350d81393f4463eea1a91e7c Reviewed-on: https://chromium-review.googlesource.com/366943 Commit-Ready: Shawn N <shawnn@chromium.org> Tested-by: Shawn N <shawnn@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--chip/npcx/adc.c24
1 files changed, 7 insertions, 17 deletions
diff --git a/chip/npcx/adc.c b/chip/npcx/adc.c
index cc89a31e98..6829a627a0 100644
--- a/chip/npcx/adc.c
+++ b/chip/npcx/adc.c
@@ -60,17 +60,6 @@ void adc_freq_changed(void)
DECLARE_HOOK(HOOK_FREQ_CHANGE, adc_freq_changed, HOOK_PRIO_DEFAULT);
/**
- * Get current voltage data of the specified channel.
- *
- * @param input_ch npcx input channel to read
- * @return ADC channel voltage data.(Range: 0~1023)
- */
-static int get_channel_data(enum npcx_adc_input_channel input_ch)
-{
- return GET_FIELD(NPCX_CHNDAT(input_ch), NPCX_CHNDAT_CHDAT_FIELD);
-}
-
-/**
* Flush an ADC sequencer and initiate a read.
*
* @param input_ch operation channel
@@ -105,11 +94,11 @@ static int start_single_and_wait(enum npcx_adc_input_channel input_ch
SET_BIT(NPCX_ADCCNF, NPCX_ADCCNF_START);
/* Wait for interrupt */
- event = task_wait_event(timeout);
+ event = task_wait_event_mask(TASK_EVENT_ADC_DONE, timeout);
task_waiting = TASK_ID_INVALID;
- return event != TASK_EVENT_TIMER;
+ return (event == TASK_EVENT_ADC_DONE);
}
@@ -124,15 +113,17 @@ int adc_read_channel(enum adc_channel ch)
const struct adc_t *adc = adc_channels + ch;
static struct mutex adc_lock;
int value;
+ uint16_t chn_data;
mutex_lock(&adc_lock);
if (start_single_and_wait(adc->input_ch, ADC_TIMEOUT_US)) {
+ chn_data = NPCX_CHNDAT(adc->input_ch);
if ((adc->input_ch ==
GET_FIELD(NPCX_ASCADD, NPCX_ASCADD_SADDR_FIELD))
- && (IS_BIT_SET(NPCX_CHNDAT(adc->input_ch),
+ && (IS_BIT_SET(chn_data,
NPCX_CHNDAT_NEW))) {
- value = get_channel_data(adc->input_ch) *
+ value = GET_FIELD(chn_data, NPCX_CHNDAT_CHDAT_FIELD) *
adc->factor_mul / adc->factor_div + adc->shift;
} else {
value = ADC_READ_ERROR;
@@ -167,7 +158,7 @@ void adc_interrupt(void)
/* Wake up the task which was waiting for the interrupt */
if (task_waiting != TASK_ID_INVALID)
- task_wake(task_waiting);
+ task_set_event(task_waiting, TASK_EVENT_ADC_DONE, 0);
}
}
DECLARE_IRQ(NPCX_IRQ_ADC, adc_interrupt, 3);
@@ -205,6 +196,5 @@ static void adc_init(void)
/* Enable IRQs */
task_enable_irq(NPCX_IRQ_ADC);
-
}
DECLARE_HOOK(HOOK_INIT, adc_init, HOOK_PRIO_INIT_ADC);