summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-10-29 12:56:29 -0700
committerGerrit <chrome-bot@google.com>2012-10-30 10:45:07 -0700
commitfdd3d90bd78fd753356d8aa3373e066141851a35 (patch)
tree357e4c651b98b8907ef19e0ea8429f506bd8904c
parent1d916d7c6b25de10c870cf7f35a44d3654d9f099 (diff)
downloadchrome-ec-fdd3d90bd78fd753356d8aa3373e066141851a35.tar.gz
Clean up ADC module
ADC config structs are now chip-specific; this saves code size (several hundred bytes on LM4, since no need for 24-entry ADC channel to GPIO mapping table). BUG=chrome-os-partner:15579 BRANCH=none TEST='adc' with system on and off; ChargerCurrent should be bigger when on. Change-Id: Ia88b3f043438bec049f2d2ad39fc42dcf86d9424 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/36798
-rw-r--r--board/bds/board.c4
-rw-r--r--board/link/board.c8
-rw-r--r--board/spring/board.c6
-rw-r--r--chip/lm4/adc.c117
-rw-r--r--chip/lm4/lm4_adc.h26
-rw-r--r--chip/stm32/stm32_adc.h9
-rw-r--r--include/adc.h30
7 files changed, 96 insertions, 104 deletions
diff --git a/board/bds/board.c b/board/bds/board.c
index 04e3d56c67..ccbe69b38c 100644
--- a/board/bds/board.c
+++ b/board/bds/board.c
@@ -19,7 +19,7 @@ const struct adc_t adc_channels[ADC_CH_COUNT] = {
* = -225 * ADC_VALUE / ADC_READ_MAX + 420.5
*/
{"ECTemp", LM4_ADC_SEQ0, -225, ADC_READ_MAX, 420,
- LM4_AIN_NONE, 0x0e /* TS0 | IE0 | END0 */},
+ LM4_AIN_NONE, 0x0e /* TS0 | IE0 | END0 */, 0, 0},
/* Charger current is mapped from 0~4000mA to 0~1.6V.
* And ADC maps 0~3.3V to ADC_READ_MAX.
@@ -28,7 +28,7 @@ const struct adc_t adc_channels[ADC_CH_COUNT] = {
* board, but that's good enough for debugging the ADC.
*/
{"BDSPot", LM4_ADC_SEQ1, 33 * 4000, ADC_READ_MAX * 16, 0,
- LM4_AIN(0), 0x06 /* IE0 | END0 */},
+ LM4_AIN(0), 0x06 /* IE0 | END0 */, LM4_GPIO_E, (1<<3)},
};
diff --git a/board/link/board.c b/board/link/board.c
index 5f7fbf1106..e4fbb53423 100644
--- a/board/link/board.c
+++ b/board/link/board.c
@@ -5,8 +5,7 @@
/* EC for Link board configuration */
#include "adc.h"
-#include "board.h"
-#include "config.h"
+#include "common.h"
#include "gpio.h"
#include "i2c.h"
#include "lm4_adc.h"
@@ -22,7 +21,6 @@
#define power_button_interrupt NULL
#endif
-
/* GPIO signal list. Must match order from enum gpio_signal. */
const struct gpio_info gpio_list[GPIO_COUNT] = {
/* Inputs with interrupt handlers are first for efficiency */
@@ -126,13 +124,13 @@ const struct adc_t adc_channels[ADC_CH_COUNT] = {
* = -225 * ADC_VALUE / ADC_READ_MAX + 420.5
*/
{"ECTemp", LM4_ADC_SEQ0, -225, ADC_READ_MAX, 420,
- LM4_AIN_NONE, 0x0e /* TS0 | IE0 | END0 */},
+ LM4_AIN_NONE, 0x0e /* TS0 | IE0 | END0 */, 0, 0},
/* Charger current is mapped from 0~4000mA to 0~1.6V.
* And ADC maps 0~3.3V to ADC_READ_MAX.
*/
{"ChargerCurrent", LM4_ADC_SEQ1, 33 * 4000, ADC_READ_MAX * 16, 0,
- LM4_AIN(11), 0x06 /* IE0 | END0 */},
+ LM4_AIN(11), 0x06 /* IE0 | END0 */, LM4_GPIO_B, (1<<5)},
};
/* I2C ports */
diff --git a/board/spring/board.c b/board/spring/board.c
index 5542f2354f..9316aaad52 100644
--- a/board/spring/board.c
+++ b/board/spring/board.c
@@ -99,11 +99,11 @@ const struct gpio_info gpio_list[GPIO_COUNT] = {
/* ADC channels */
const struct adc_t adc_channels[ADC_CH_COUNT] = {
/* Micro USB ID pin. Raw ADC value. */
- [ADC_CH_USB_ID] = {"USB_ID", 0, 1, 1, 0, STM32_AIN(5), 0},
+ [ADC_CH_USB_ID] = {"USB_ID", 1, 1, 0, STM32_AIN(5)},
/* Micro USB D+ sense pin. Raw ADC value. */
- [ADC_CH_USB_DP_SNS] = {"USB_DP_SNS", 0, 1, 1, 0, STM32_AIN(2), 0},
+ [ADC_CH_USB_DP_SNS] = {"USB_DP_SNS", 1, 1, 0, STM32_AIN(2)},
/* Micro USB D- sense pin. Raw ADC value. */
- [ADC_CH_USB_DN_SNS] = {"USB_DN_SNS", 0, 1, 1, 0, STM32_AIN(4), 0},
+ [ADC_CH_USB_DN_SNS] = {"USB_DN_SNS", 1, 1, 0, STM32_AIN(4)},
};
void configure_board(void)
diff --git a/chip/lm4/adc.c b/chip/lm4/adc.c
index b2d3479eef..3bac9415c5 100644
--- a/chip/lm4/adc.c
+++ b/chip/lm4/adc.c
@@ -16,68 +16,44 @@
#include "timer.h"
#include "util.h"
-extern const struct adc_t adc_channels[ADC_CH_COUNT];
-
static task_id_t task_waiting_on_ss[LM4_ADC_SEQ_COUNT];
-/* GPIO port and mask for AINs. */
-const uint32_t ain_port[24][2] = {
- {LM4_GPIO_E, (1<<3)},
- {LM4_GPIO_E, (1<<2)},
- {LM4_GPIO_E, (1<<1)},
- {LM4_GPIO_E, (1<<0)},
- {LM4_GPIO_D, (1<<7)},
- {LM4_GPIO_D, (1<<6)},
- {LM4_GPIO_D, (1<<5)},
- {LM4_GPIO_D, (1<<4)},
- {LM4_GPIO_E, (1<<5)},
- {LM4_GPIO_E, (1<<4)},
- {LM4_GPIO_B, (1<<4)},
- {LM4_GPIO_B, (1<<5)},
- {LM4_GPIO_D, (1<<3)},
- {LM4_GPIO_D, (1<<2)},
- {LM4_GPIO_D, (1<<1)},
- {LM4_GPIO_D, (1<<0)},
- {LM4_GPIO_K, (1<<0)},
- {LM4_GPIO_K, (1<<1)},
- {LM4_GPIO_K, (1<<2)},
- {LM4_GPIO_K, (1<<3)},
- {LM4_GPIO_E, (1<<7)},
- {LM4_GPIO_E, (1<<6)},
- {LM4_GPIO_N, (1<<1)},
- {LM4_GPIO_N, (1<<0)},
-};
-
-
static void configure_gpio(void)
{
int i;
/* Use analog function for AIN */
for (i = 0; i < ADC_CH_COUNT; ++i) {
- int id = adc_channels[i].channel;
- if (id != LM4_AIN_NONE)
- gpio_set_alternate_function(ain_port[id][0],
- ain_port[id][1],
+ if (adc_channels[i].gpio_mask) {
+ gpio_set_alternate_function(adc_channels[i].gpio_port,
+ adc_channels[i].gpio_mask,
1);
+ }
}
}
-
-int lm4_adc_flush_and_read(enum lm4_adc_sequencer seq)
+/**
+ * Flush an ADC sequencer and initiate a read.
+ *
+ * @param seq Sequencer to read
+ * @return Raw ADC value.
+ */
+static int lm4_adc_flush_and_read(enum lm4_adc_sequencer seq)
{
- /* TODO: right now we have only a single channel so this is
- * simple. When we have multiple channels, should we...
+ /*
+ * TODO: right now we have only a single channel so this is simple.
+ * When we have multiple channels, should we...
*
- * 1) Read them all using a timer interrupt, and then return
- * the most recent value? This is lowest-latency for the
- * caller, but won't return accurate data if read frequently.
+ * 1) Read them all using a timer interrupt, and then return the most
+ * recent value? This is lowest-latency for the caller, but won't
+ * return accurate data if read frequently.
*
- * 2) Reserve SS3 for reading a single value, and configure it
- * on each read? Needs mutex if we could have multiple
- * callers; doesn't matter if just used for debugging.
+ * 2) Reserve SS3 for reading a single value, and configure it on each
+ * read? Needs mutex if we could have multiple callers; doesn't matter
+ * if just used for debugging.
*
- * 3) Both? */
+ * 3) Both?
+ */
volatile uint32_t scratch __attribute__((unused));
int event;
@@ -85,8 +61,10 @@ int lm4_adc_flush_and_read(enum lm4_adc_sequencer seq)
while (!(LM4_ADC_SSFSTAT(seq) & 0x100))
scratch = LM4_ADC_SSFIFO(seq);
- /* TODO: This assumes we don't have multiple tasks accessing
- * the same sequencer. Add mutex lock if needed. */
+ /*
+ * This assumes we don't have multiple tasks accessing the same
+ * sequencer. Add mutex lock if needed.
+ */
task_waiting_on_ss[seq] = task_get_current();
/* Clear the interrupt status */
@@ -105,11 +83,18 @@ int lm4_adc_flush_and_read(enum lm4_adc_sequencer seq)
return LM4_ADC_SSFIFO(seq);
}
-
-int lm4_adc_configure(enum lm4_adc_sequencer seq,
- int ain_id,
- int ssctl)
+/**
+ * Configure an ADC sequencer to be dedicated for an ADC input.
+ *
+ * @param seq Sequencer to configure
+ * @param ain_id ADC input to use
+ * @param ssctl Value for sampler sequencer control register
+ *
+ */
+static void lm4_adc_configure(const struct adc_t *adc)
{
+ const enum lm4_adc_sequencer seq = adc->sequencer;
+
/* Configure sample sequencer */
LM4_ADC_ADCACTSS &= ~(0x01 << seq);
@@ -117,22 +102,19 @@ int lm4_adc_configure(enum lm4_adc_sequencer seq,
LM4_ADC_ADCEMUX = (LM4_ADC_ADCEMUX & ~(0xf << (seq * 4))) | 0x00;
/* Sample internal temp sensor */
- if (ain_id != LM4_AIN_NONE) {
- LM4_ADC_SSMUX(seq) = ain_id & 0xf;
- LM4_ADC_SSEMUX(seq) = ain_id >> 4;
- } else {
+ if (adc->channel == LM4_AIN_NONE) {
LM4_ADC_SSMUX(seq) = 0x00;
LM4_ADC_SSEMUX(seq) = 0x00;
+ } else {
+ LM4_ADC_SSMUX(seq) = adc->channel & 0xf;
+ LM4_ADC_SSEMUX(seq) = adc->channel >> 4;
}
- LM4_ADC_SSCTL(seq) = ssctl;
+ LM4_ADC_SSCTL(seq) = adc->flag;
/* Enable sample sequencer */
LM4_ADC_ADCACTSS |= 0x01 << seq;
-
- return EC_SUCCESS;
}
-
int adc_read_channel(enum adc_channel ch)
{
const struct adc_t *adc = adc_channels + ch;
@@ -146,7 +128,9 @@ int adc_read_channel(enum adc_channel ch)
/*****************************************************************************/
/* Interrupt handlers */
-/* Handles an interrupt on the specified sample sequencer. */
+/**
+ * Handle an interrupt on the specified sample sequencer.
+ */
static void handle_interrupt(int ss)
{
int id = task_waiting_on_ss[ss];
@@ -159,7 +143,6 @@ static void handle_interrupt(int ss)
task_wake(id);
}
-
static void ss0_interrupt(void) { handle_interrupt(0); }
static void ss1_interrupt(void) { handle_interrupt(1); }
static void ss2_interrupt(void) { handle_interrupt(2); }
@@ -173,7 +156,7 @@ DECLARE_IRQ(LM4_IRQ_ADC0_SS3, ss3_interrupt, 2);
/*****************************************************************************/
/* Console commands */
-#ifdef CONSOLE_COMMAND_ECTEMP
+#ifdef CONFIG_CMD_ECTEMP
static int command_ectemp(int argc, char **argv)
{
int t = adc_read_channel(ADC_CH_EC_TEMP);
@@ -186,7 +169,6 @@ DECLARE_CONSOLE_COMMAND(ectemp, command_ectemp,
NULL);
#endif
-
static int command_adc(int argc, char **argv)
{
int i;
@@ -208,7 +190,6 @@ DECLARE_CONSOLE_COMMAND(adc, command_adc,
static void adc_init(void)
{
int i;
- const struct adc_t *adc;
/* Configure GPIOs */
configure_gpio();
@@ -248,9 +229,7 @@ static void adc_init(void)
task_enable_irq(LM4_IRQ_ADC0_SS3);
/* Initialize ADC sequencer */
- for (i = 0; i < ADC_CH_COUNT; ++i) {
- adc = adc_channels + i;
- lm4_adc_configure(adc->sequencer, adc->channel, adc->flag);
- }
+ for (i = 0; i < ADC_CH_COUNT; ++i)
+ lm4_adc_configure(adc_channels + i);
}
DECLARE_HOOK(HOOK_INIT, adc_init, HOOK_PRIO_DEFAULT);
diff --git a/chip/lm4/lm4_adc.h b/chip/lm4/lm4_adc.h
index 98f5293646..69479ac265 100644
--- a/chip/lm4/lm4_adc.h
+++ b/chip/lm4/lm4_adc.h
@@ -14,11 +14,25 @@ enum lm4_adc_sequencer
LM4_ADC_SEQ1,
LM4_ADC_SEQ2,
LM4_ADC_SEQ3,
-
LM4_ADC_SEQ_COUNT
};
-/* Minimum and maximum values returned by lm4_adc_flush_and_read(). */
+/* Data structure to define ADC channels. */
+struct adc_t {
+ const char *name;
+ enum lm4_adc_sequencer sequencer;
+ int factor_mul;
+ int factor_div;
+ int shift;
+ int channel;
+ int flag;
+ uint32_t gpio_port;
+ uint8_t gpio_mask;
+};
+
+extern const struct adc_t adc_channels[ADC_CH_COUNT];
+
+/* Minimum and maximum values returned by raw ADC read. */
#define ADC_READ_MIN 0
#define ADC_READ_MAX 4095
@@ -31,12 +45,4 @@ enum lm4_adc_sequencer
/* Dummy value for "channel" in adc_t if we don't have an external channel. */
#define LM4_AIN_NONE (-1)
-/* Flush an ADC sequencer and initiate a read. Return raw ADC value. */
-int lm4_adc_flush_and_read(enum lm4_adc_sequencer);
-
-/* Configure an ADC sequencer to be dedicated for an ADC input "ain_id".
- * Value in "ssctl" field is passed to sampler sequencer control register.
- */
-int lm4_adc_configure(enum lm4_adc_sequencer, int ain_id, int ssctl);
-
#endif /* __CROS_EC_LM4_ADC_H */
diff --git a/chip/stm32/stm32_adc.h b/chip/stm32/stm32_adc.h
index 01e67c603b..d67459972c 100644
--- a/chip/stm32/stm32_adc.h
+++ b/chip/stm32/stm32_adc.h
@@ -8,6 +8,15 @@
#ifndef __CROS_EC_STM32_ADC_H
#define __CROS_EC_STM32_ADC_H
+/* Data structure to define ADC channels. */
+struct adc_t {
+ const char *name;
+ int factor_mul;
+ int factor_div;
+ int shift;
+ int channel;
+};
+
extern const struct adc_t adc_channels[ADC_CH_COUNT];
/* Minimum and maximum values returned by adc_read_channel(). */
diff --git a/include/adc.h b/include/adc.h
index fe1296cc3b..646298ca76 100644
--- a/include/adc.h
+++ b/include/adc.h
@@ -9,24 +9,24 @@
#define __CROS_EC_ADC_H
#include "common.h"
-#include "board.h"
-/* Data structure to define ADC channels. */
-struct adc_t
-{
- const char* name;
- int sequencer;
- int factor_mul;
- int factor_div;
- int shift;
- int channel;
- int flag;
-};
-
-/* Read ADC channel. */
+/**
+ * Read an ADC channel.
+ *
+ * @param ch Channel to read
+ *
+ * @return The scaled ADC value, or ADC_READ_ERROR if error.
+ */
int adc_read_channel(enum adc_channel ch);
-/* Read all ADC channels. Return non-zero on error. */
+/**
+ * Read all ADC channels.
+ *
+ * @param data Destination array for channel data; must be
+ * ADC_CH_COUNT elements long.
+ *
+ * @return EC_SUCCESS, or non-zero on error.
+ */
int adc_read_all_channels(int *data);
#endif /* __CROS_EC_ADC_H */