diff options
Diffstat (limited to 'chip/mchp/adc.c')
-rw-r--r-- | chip/mchp/adc.c | 157 |
1 files changed, 0 insertions, 157 deletions
diff --git a/chip/mchp/adc.c b/chip/mchp/adc.c deleted file mode 100644 index d40a8a9d1c..0000000000 --- a/chip/mchp/adc.c +++ /dev/null @@ -1,157 +0,0 @@ -/* Copyright 2017 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "adc.h" -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "util.h" -#include "tfdp_chip.h" - -/* - * Conversion on a single channel takes less than 12 ms. Set timeout to - * 15 ms so that we have a 3-ms margin. - */ -#define ADC_SINGLE_READ_TIME 15000 - -struct mutex adc_lock; - -/* - * Volatile should not be needed. - * ADC ISR only reads task_waiting. - * Two other non-ISR routines only write task_waiting when - * interrupt is disabled or before starting ADC. - */ -static task_id_t task_waiting; - -/* - * Start ADC single-shot conversion. - * 1. Disable ADC interrupt. - * 2. Clear sticky hardware status. - * 3. Start conversion. - * 4. Enable interrupt. - * 5. Wait with timeout for ADC ISR to - * to set TASK_EVENT_TIMER. - */ -static int start_single_and_wait(int timeout) -{ - int event; - - MCHP_INT_DISABLE(MCHP_ADC_GIRQ) = MCHP_ADC_GIRQ_SINGLE_BIT; - task_waiting = task_get_current(); - - /* clear all R/W1C channel status */ - MCHP_ADC_STS = 0xffffu; - /* clear R/W1C single done status */ - MCHP_ADC_CTRL |= BIT(7); - /* clear GIRQ single status */ - MCHP_INT_SOURCE(MCHP_ADC_GIRQ) = MCHP_ADC_GIRQ_SINGLE_BIT; - /* make sure all writes are issued before starting conversion */ - asm volatile ("dsb"); - - /* Start conversion */ - MCHP_ADC_CTRL |= BIT(1); - - MCHP_INT_ENABLE(MCHP_ADC_GIRQ) = MCHP_ADC_GIRQ_SINGLE_BIT; - - /* Wait for interrupt, ISR disables interrupt */ - event = task_wait_event(timeout); - task_waiting = TASK_ID_INVALID; - return event != TASK_EVENT_TIMER; -} - -int adc_read_channel(enum adc_channel ch) -{ - const struct adc_t *adc = adc_channels + ch; - int value; - - mutex_lock(&adc_lock); - - MCHP_ADC_SINGLE = 1 << adc->channel; - - if (start_single_and_wait(ADC_SINGLE_READ_TIME)) - value = (MCHP_ADC_READ(adc->channel) * adc->factor_mul) / - adc->factor_div + adc->shift; - else - value = ADC_READ_ERROR; - - mutex_unlock(&adc_lock); - return value; -} - -int adc_read_all_channels(int *data) -{ - int i; - int ret = EC_SUCCESS; - const struct adc_t *adc; - - mutex_lock(&adc_lock); - - MCHP_ADC_SINGLE = 0; - for (i = 0; i < ADC_CH_COUNT; ++i) - MCHP_ADC_SINGLE |= 1 << adc_channels[i].channel; - - if (!start_single_and_wait(ADC_SINGLE_READ_TIME * ADC_CH_COUNT)) { - ret = EC_ERROR_TIMEOUT; - goto exit_all_channels; - } - - for (i = 0; i < ADC_CH_COUNT; ++i) { - adc = adc_channels + i; - data[i] = (MCHP_ADC_READ(adc->channel) * adc->factor_mul) / - adc->factor_div + adc->shift; - } - -exit_all_channels: - mutex_unlock(&adc_lock); - - return ret; -} - -/* - * Enable GPIO pins. - * Using MEC17xx direct mode interrupts. Do not - * set Interrupt Aggregator Block Enable bit - * for GIRQ containing ADC. - */ -static void adc_init(void) -{ - trace0(0, ADC, 0, "adc_init"); - - gpio_config_module(MODULE_ADC, 1); - - /* clear ADC sleep enable */ - MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_ADC); - - /* Activate ADC module */ - MCHP_ADC_CTRL |= BIT(0); - - /* Enable interrupt */ - task_waiting = TASK_ID_INVALID; - MCHP_INT_ENABLE(MCHP_ADC_GIRQ) = MCHP_ADC_GIRQ_SINGLE_BIT; - task_enable_irq(MCHP_IRQ_ADC_SNGL); -} -DECLARE_HOOK(HOOK_INIT, adc_init, HOOK_PRIO_INIT_ADC); - -void adc_interrupt(void) -{ - MCHP_INT_DISABLE(MCHP_ADC_GIRQ) = MCHP_ADC_GIRQ_SINGLE_BIT; - - /* clear individual chan conversion status */ - MCHP_ADC_STS = 0xffffu; - - /* Clear interrupt status bit */ - MCHP_ADC_CTRL |= BIT(7); - - MCHP_INT_SOURCE(MCHP_ADC_GIRQ) = MCHP_ADC_GIRQ_SINGLE_BIT; - - if (task_waiting != TASK_ID_INVALID) - task_wake(task_waiting); -} -DECLARE_IRQ(MCHP_IRQ_ADC_SNGL, adc_interrupt, 2); |