diff options
Diffstat (limited to 'chip/stm32/adc-stm32l.c')
-rw-r--r-- | chip/stm32/adc-stm32l.c | 170 |
1 files changed, 0 insertions, 170 deletions
diff --git a/chip/stm32/adc-stm32l.c b/chip/stm32/adc-stm32l.c deleted file mode 100644 index c1f1cfae4a..0000000000 --- a/chip/stm32/adc-stm32l.c +++ /dev/null @@ -1,170 +0,0 @@ -/* Copyright 2012 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 "clock.h" -#include "dma.h" -#include "hooks.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -#define ADC_SINGLE_READ_TIMEOUT 3000 /* 3 ms */ - -struct mutex adc_lock; - -static int restore_clock; - -static inline void adc_set_channel(int sample_id, int channel) -{ - uint32_t mask, val; - volatile uint32_t *sqr_reg; - int reg_id; - - reg_id = 5 - sample_id / 6; - - mask = 0x1f << ((sample_id % 6) * 5); - val = channel << ((sample_id % 6) * 5); - sqr_reg = &STM32_ADC_SQR(reg_id); - - *sqr_reg = (*sqr_reg & ~mask) | val; -} - -static void adc_configure(int ain_id) -{ - /* Set ADC channel */ - adc_set_channel(0, ain_id); - - /* Disable DMA */ - STM32_ADC_CR2 &= ~BIT(8); - - /* Disable scan mode */ - STM32_ADC_CR1 &= ~BIT(8); -} - -static void adc_configure_all(void) -{ - int i; - - /* Set ADC channels */ - STM32_ADC_SQR1 = (ADC_CH_COUNT - 1) << 20; - for (i = 0; i < ADC_CH_COUNT; ++i) - adc_set_channel(i, adc_channels[i].channel); - - /* Enable DMA */ - STM32_ADC_CR2 |= BIT(8); - - /* Enable scan mode */ - STM32_ADC_CR1 |= BIT(8); -} - -static inline int adc_powered(void) -{ - return STM32_ADC_SR & BIT(6); /* ADONS */ -} - -static void adc_enable_clock(void) -{ - STM32_RCC_APB2ENR |= BIT(9); - /* ADCCLK = HSI / 2 = 8MHz*/ - STM32_ADC_CCR |= BIT(16); -} - -static void adc_init(void) -{ - /* - * For STM32L, ADC clock source is HSI/2 = 8 MHz. HSI must be enabled - * for ADC. - * - * Note that we are not powering on ADC on EC initialization because - * STM32L ADC module requires HSI clock. Instead, ADC module is powered - * on/off in adc_prepare()/adc_release(). - */ - - /* Enable ADC clock. */ - adc_enable_clock(); - - if (!adc_powered()) - /* Power on ADC module */ - STM32_ADC_CR2 |= BIT(0); /* ADON */ - - /* Set right alignment */ - STM32_ADC_CR2 &= ~BIT(11); - - /* - * Set sample time of all channels to 16 cycles. - * Conversion takes (12+16)/8M = 3.34 us. - */ - STM32_ADC_SMPR1 = 0x24924892; - STM32_ADC_SMPR2 = 0x24924892; - STM32_ADC_SMPR3 = 0x24924892; -} - -static void adc_prepare(void) -{ - if (!adc_powered()) { - clock_enable_module(MODULE_ADC, 1); - adc_init(); - restore_clock = 1; - } -} - -static void adc_release(void) -{ - if (restore_clock) { - clock_enable_module(MODULE_ADC, 0); - restore_clock = 0; - } - - /* - * Power down the ADC. The ADC consumes a non-trivial amount of power, - * so it's wasteful to leave it on. - */ - if (adc_powered()) - STM32_ADC_CR2 = 0; -} - -static inline int adc_conversion_ended(void) -{ - return STM32_ADC_SR & BIT(1); -} - -int adc_read_channel(enum adc_channel ch) -{ - const struct adc_t *adc = adc_channels + ch; - int value; - timestamp_t deadline; - - mutex_lock(&adc_lock); - - adc_prepare(); - - adc_configure(adc->channel); - - /* Clear EOC bit */ - STM32_ADC_SR &= ~BIT(1); - - /* Start conversion */ - STM32_ADC_CR2 |= BIT(30); /* SWSTART */ - - /* Wait for EOC bit set */ - deadline.val = get_time().val + ADC_SINGLE_READ_TIMEOUT; - value = ADC_READ_ERROR; - do { - if (adc_conversion_ended()) { - value = STM32_ADC_DR & ADC_READ_MAX; - break; - } - } while (!timestamp_expired(deadline, NULL)); - - adc_release(); - - mutex_unlock(&adc_lock); - return (value == ADC_READ_ERROR) ? ADC_READ_ERROR : - value * adc->factor_mul / adc->factor_div + adc->shift; -} |