summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/bds/board.c13
-rw-r--r--board/bds/board.h13
-rw-r--r--board/bolt/board.c37
-rw-r--r--board/bolt/board.h16
-rw-r--r--board/daisy/board.c20
-rw-r--r--board/daisy/board.h9
-rw-r--r--board/falco/board.c27
-rw-r--r--board/falco/board.h15
-rw-r--r--board/host/board.c5
-rw-r--r--board/host/board.h6
-rw-r--r--board/kirby/board.c21
-rw-r--r--board/kirby/board.h10
-rw-r--r--board/link/board.c37
-rw-r--r--board/link/board.h19
-rw-r--r--board/mccroskey/board.c9
-rw-r--r--board/mccroskey/board.h7
-rw-r--r--board/peppy/board.c25
-rw-r--r--board/peppy/board.h15
-rw-r--r--board/pit/board.c21
-rw-r--r--board/pit/board.h10
-rw-r--r--board/puppy/board.c21
-rw-r--r--board/puppy/board.h10
-rw-r--r--board/slippy/board.c25
-rw-r--r--board/slippy/board.h15
-rw-r--r--board/snow/board.c9
-rw-r--r--board/snow/board.h8
-rw-r--r--board/spring/board.c9
-rw-r--r--board/spring/board.h7
-rw-r--r--board/wolf/board.c25
-rw-r--r--board/wolf/board.h15
-rw-r--r--chip/host/gpio.c11
-rw-r--r--chip/lm4/gpio.c80
-rw-r--r--chip/lm4/i2c.c26
-rw-r--r--chip/lm4/lpc.c16
-rw-r--r--chip/lm4/peci.c17
-rw-r--r--chip/lm4/pwm_fan.c2
-rw-r--r--chip/lm4/pwm_kblight.c2
-rw-r--r--chip/lm4/registers.h17
-rw-r--r--chip/lm4/spi.c6
-rw-r--r--chip/lm4/uart.c25
-rw-r--r--chip/stm32/gpio-stm32f.c34
-rw-r--r--chip/stm32/gpio-stm32l.c28
-rw-r--r--chip/stm32/i2c-stm32l.c3
-rw-r--r--chip/stm32/power_led.c7
-rw-r--r--chip/stm32/spi.c4
-rw-r--r--chip/stm32/uart.c4
-rw-r--r--common/gpio_common.c28
-rw-r--r--include/config.h5
-rw-r--r--include/gpio.h97
-rw-r--r--include/pwm.h10
50 files changed, 551 insertions, 350 deletions
diff --git a/board/bds/board.c b/board/bds/board.c
index 830b8fcf41..915679d4c3 100644
--- a/board/bds/board.c
+++ b/board/bds/board.c
@@ -41,10 +41,19 @@ BUILD_ASSERT(ARRAY_SIZE(i2c_ports) == I2C_PORTS_USED);
/* GPIO signal list. Must match order from enum gpio_signal. */
const struct gpio_info gpio_list[] = {
- {"RECOVERYn", LM4_GPIO_D, (1<<1), GPIO_PULL_UP, NULL},
- {"DEBUG_LED", LM4_GPIO_A, (1<<7), GPIO_OUT_LOW, NULL},
+ {"RECOVERYn", GPIO_D, (1<<1), GPIO_PULL_UP, NULL},
+ {"DEBUG_LED", GPIO_A, (1<<7), GPIO_OUT_LOW, NULL},
/* Unimplemented signals which we need to emulate for now */
GPIO_SIGNAL_NOT_IMPLEMENTED("WP"),
GPIO_SIGNAL_NOT_IMPLEMENTED("ENTERING_RW"),
};
BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT);
+
+/* Pins with alternate functions */
+const struct gpio_alt_func gpio_alt_funcs[] = {
+ {GPIO_A, 0x03, 1, MODULE_UART}, /* UART0 */
+ {GPIO_G, 0x40, 3, MODULE_I2C}, /* I2C5 SCL */
+ {GPIO_G, 0x80, 3, GPIO_OPEN_DRAIN}, /* I2C5 SDA */
+ {GPIO_B, 0x03, 1, MODULE_UART}, /* UART1 */
+};
+const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
diff --git a/board/bds/board.h b/board/bds/board.h
index 61c7c5a7f9..9d4672a34d 100644
--- a/board/bds/board.h
+++ b/board/bds/board.h
@@ -27,8 +27,14 @@
#ifndef __ASSEMBLER__
-enum adc_channel
-{
+/* Module IDs */
+/* TODO(rspangler): use this in place of enum console_channel as well */
+enum module_id {
+ MODULE_I2C,
+ MODULE_UART,
+};
+
+enum adc_channel {
ADC_CH_EC_TEMP = 0, /* EC internal die temperature in degrees K. */
ADC_CH_BDS_POT, /* BDS pot input. */
ADC_CH_COUNT
@@ -39,9 +45,8 @@ enum adc_channel
/* Number of I2C ports used */
#define I2C_PORTS_USED 1
-/* GPIOs for second UART port */
+/* Second UART port */
#define CONFIG_UART_HOST 1
-#define CONFIG_UART_HOST_GPIOS_PB0_1
/* GPIO signal list */
enum gpio_signal {
diff --git a/board/bolt/board.c b/board/bolt/board.c
index ccdc8bce87..de4a3d18e9 100644
--- a/board/bolt/board.c
+++ b/board/bolt/board.c
@@ -127,6 +127,25 @@ const struct gpio_info gpio_list[] = {
};
BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT);
+/* Pins with alternate functions */
+const struct gpio_alt_func gpio_alt_funcs[] = {
+ {GPIO_A, 0x03, 1, MODULE_UART}, /* UART0 */
+ {GPIO_A, 0x40, 3, MODULE_I2C}, /* I2C1 SCL */
+ {GPIO_A, 0x80, 3, MODULE_I2C, GPIO_OPEN_DRAIN}, /* I2C1 SDA */
+ {GPIO_B, 0x04, 3, MODULE_I2C}, /* I2C0 SCL */
+ {GPIO_B, 0x08, 3, MODULE_I2C, GPIO_OPEN_DRAIN}, /* I2C0 SDA */
+ {GPIO_B, 0x40, 3, MODULE_I2C}, /* I2C5 SCL */
+ {GPIO_B, 0x80, 3, MODULE_I2C, GPIO_OPEN_DRAIN}, /* I2C5 SDA */
+ {GPIO_G, 0x30, 1, MODULE_UART}, /* UART2 */
+ {GPIO_J, 0x40, 1, MODULE_PECI}, /* PECI Tx */
+ {GPIO_J, 0x80, 0, MODULE_PECI, GPIO_ANALOG}, /* PECI Rx */
+ {GPIO_L, 0x3f, 15, MODULE_LPC}, /* LPC */
+ {GPIO_M, 0x33, 15, MODULE_LPC}, /* LPC */
+ {GPIO_N, 0x0c, 1, MODULE_PWM_FAN}, /* Fan0 PWM/tach */
+ {GPIO_N, 0x40, 1, MODULE_PWM_KBLIGHT}, /* Fan1 PWM */
+};
+const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
+
/* x86 signal list. Must match order of enum x86_signal. */
const struct x86_signal_info x86_signal_list[] = {
{GPIO_PP5000_PGOOD, 1, "PGOOD_PP5000"},
@@ -193,15 +212,6 @@ struct keyboard_scan_config keyscan_config = {
};
/**
- * Configure the GPIOs for the pwm module.
- */
-void configure_fan_gpios(void)
-{
- /* PN2:3 alternate function 1 = channel 0 PWM/tach */
- gpio_set_alternate_function(LM4_GPIO_N, 0x0c, 1);
-}
-
-/**
* Perform necessary actions on host wake events.
*/
void board_process_wake_events(uint32_t active_wake_events)
@@ -217,12 +227,3 @@ void board_process_wake_events(uint32_t active_wake_events)
else
gpio_set_level(GPIO_PCH_WAKE_L, 1);
}
-
-/**
- * Configure the GPIOs for the pwm module.
- */
-void configure_kblight_gpios(void)
-{
- /* PN6 alternate function 1 = channel 4 PWM */
- gpio_set_alternate_function(LM4_GPIO_N, 0x40, 1);
-}
diff --git a/board/bolt/board.h b/board/bolt/board.h
index 3fed8c42f4..c646456a95 100644
--- a/board/bolt/board.h
+++ b/board/bolt/board.h
@@ -42,6 +42,7 @@
#define CONFIG_PWM_FAN
#define CONFIG_PWM_KBLIGHT
#define CONFIG_TEMP_SENSOR
+#define CONFIG_UART_HOST 2
#define CONFIG_WIRELESS
#if 0
#define CONFIG_USB_PORT_POWER_DUMB
@@ -50,6 +51,17 @@
#ifndef __ASSEMBLER__
+/* Module IDs */
+/* TODO(rspangler): use this in place of enum console_channel as well */
+enum module_id {
+ MODULE_I2C,
+ MODULE_LPC,
+ MODULE_PECI,
+ MODULE_PWM_FAN,
+ MODULE_PWM_KBLIGHT,
+ MODULE_UART,
+};
+
/* PWM channels */
#define FAN_CH_CPU 2 /* CPU fan */
#define FAN_CH_KBLIGHT 4 /* Keyboard backlight */
@@ -73,10 +85,6 @@
/* USB ports */
#define USB_PORT_COUNT 2
-/* GPIOs for second UART port */
-#define CONFIG_UART_HOST 2
-#define CONFIG_UART_HOST_GPIOS_PG4_5
-
/* GPIO signal definitions. */
enum gpio_signal {
/* Inputs with interrupt handlers are first for efficiency */
diff --git a/board/daisy/board.c b/board/daisy/board.c
index 39eda5e549..2a6eb6e3a5 100644
--- a/board/daisy/board.c
+++ b/board/daisy/board.c
@@ -101,6 +101,14 @@ const struct gpio_info gpio_list[] = {
};
BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT);
+/* Pins with alternate functions */
+const struct gpio_alt_func gpio_alt_funcs[] = {
+ {GPIO_A, 0x0004, GPIO_ALT_TIM2, MODULE_POWER_LED},
+ {GPIO_A, 0x0600, GPIO_ALT_USART, MODULE_UART},
+ {GPIO_B, 0x0cc0, GPIO_ALT_I2C, MODULE_I2C},
+};
+const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
+
/* Battery temperature ranges in degrees C */
const struct battery_temperature_ranges bat_temp_ranges = {
.start_charging_min_c = 5,
@@ -158,18 +166,6 @@ int board_i2c_host_port(void)
}
#endif /* CONFIG_I2C_HOST_AUTO */
-void board_config_post_gpio_init(void)
-{
- /* I2C SCL/SDA on PB10-11 and PB6-7 */
- gpio_set_alternate_function(GPIO_B, (1<<11) |
- (1<<10) |
- (1<<7) |
- (1<<6), GPIO_ALT_I2C);
-
- /* Select Alternate function for USART1 on pins PA9/PA10 */
- gpio_set_alternate_function(GPIO_A, (1<<9) | (1<<10), GPIO_ALT_USART);
-}
-
void keyboard_suppress_noise(void)
{
/* notify audio codec of keypress for noise suppression */
diff --git a/board/daisy/board.h b/board/daisy/board.h
index a76735a4f2..c2af3ef525 100644
--- a/board/daisy/board.h
+++ b/board/daisy/board.h
@@ -13,7 +13,6 @@
/* Optional features */
#define CONFIG_BATTERY_SMART
-#define CONFIG_BOARD_POST_GPIO_INIT
#define CONFIG_CHARGER_TPS65090
#ifdef HAS_TASK_CHIPSET
#define CONFIG_CHIPSET_GAIA
@@ -37,6 +36,14 @@
#ifndef __ASSEMBLER__
+/* Module IDs */
+/* TODO(rspangler): use this in place of enum console_channel as well */
+enum module_id {
+ MODULE_I2C,
+ MODULE_POWER_LED,
+ MODULE_UART,
+};
+
/* By default, enable all console messages except keyboard */
#define CC_DEFAULT (CC_ALL & ~CC_MASK(CC_KEYSCAN))
diff --git a/board/falco/board.c b/board/falco/board.c
index 3b9a197584..acb601b917 100644
--- a/board/falco/board.c
+++ b/board/falco/board.c
@@ -125,6 +125,24 @@ const struct gpio_info gpio_list[] = {
};
BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT);
+/* Pins with alternate functions */
+const struct gpio_alt_func gpio_alt_funcs[] = {
+ {GPIO_A, 0x03, 1, MODULE_UART}, /* UART0 */
+ {GPIO_A, 0x40, 3, MODULE_I2C}, /* I2C1 SCL */
+ {GPIO_A, 0x80, 3, MODULE_I2C, GPIO_OPEN_DRAIN}, /* I2C1 SDA */
+ {GPIO_B, 0x04, 3, MODULE_I2C}, /* I2C0 SCL */
+ {GPIO_B, 0x08, 3, MODULE_I2C, GPIO_OPEN_DRAIN}, /* I2C0 SDA */
+ {GPIO_B, 0x40, 3, MODULE_I2C}, /* I2C5 SCL */
+ {GPIO_B, 0x80, 3, MODULE_I2C, GPIO_OPEN_DRAIN}, /* I2C5 SDA */
+ {GPIO_G, 0x30, 1, MODULE_UART}, /* UART2 */
+ {GPIO_J, 0x40, 1, MODULE_PECI}, /* PECI Tx */
+ {GPIO_J, 0x80, 0, MODULE_PECI, GPIO_ANALOG}, /* PECI Rx */
+ {GPIO_L, 0x3f, 15, MODULE_LPC}, /* LPC */
+ {GPIO_M, 0x33, 15, MODULE_LPC}, /* LPC */
+ {GPIO_N, 0x0c, 1, MODULE_PWM_FAN}, /* Fan0 PWM/tach */
+};
+const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
+
/* x86 signal list. Must match order of enum x86_signal. */
const struct x86_signal_info x86_signal_list[] = {
{GPIO_PP5000_PGOOD, 1, "PGOOD_PP5000"},
@@ -195,15 +213,6 @@ struct keyboard_scan_config keyscan_config = {
};
/**
- * Configure the GPIOs for the pwm module.
- */
-void configure_fan_gpios(void)
-{
- /* PN2:3 alternate function 1 = channel 0 PWM/tach */
- gpio_set_alternate_function(LM4_GPIO_N, 0x0c, 1);
-}
-
-/**
* Perform necessary actions on host wake events.
*/
void board_process_wake_events(uint32_t active_wake_events)
diff --git a/board/falco/board.h b/board/falco/board.h
index 8abf578cb7..c0b9f656cc 100644
--- a/board/falco/board.h
+++ b/board/falco/board.h
@@ -30,11 +30,22 @@
#define CONFIG_PWM_FAN
#define CONFIG_TEMP_SENSOR
#define CONFIG_TEMP_SENSOR_G781
+#define CONFIG_UART_HOST 2
#define CONFIG_USB_PORT_POWER_DUMB
#define CONFIG_WIRELESS
#ifndef __ASSEMBLER__
+/* Module IDs */
+/* TODO(rspangler): use this in place of enum console_channel as well */
+enum module_id {
+ MODULE_I2C,
+ MODULE_LPC,
+ MODULE_PECI,
+ MODULE_PWM_FAN,
+ MODULE_UART,
+};
+
/* PWM channels */
#define FAN_CH_CPU 2 /* CPU fan */
#define FAN_CH_BL_DISPLAY 4 /* LVDS backlight (from PCH, cleaned by EC) */
@@ -57,10 +68,6 @@
/* USB ports */
#define USB_PORT_COUNT 2
-/* GPIOs for second UART port */
-#define CONFIG_UART_HOST 2
-#define CONFIG_UART_HOST_GPIOS_PG4_5
-
/* GPIO signal definitions. */
enum gpio_signal {
/* Inputs with interrupt handlers are first for efficiency */
diff --git a/board/host/board.c b/board/host/board.c
index 13389ce001..0490d2287e 100644
--- a/board/host/board.c
+++ b/board/host/board.c
@@ -20,6 +20,11 @@ const struct gpio_info gpio_list[] = {
};
BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT);
+/* Pins with alternate functions; not on simulated host platform */
+const struct gpio_alt_func gpio_alt_funcs[] = {
+};
+const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
+
static int dummy_temp_get_val(int idx, int *temp_ptr)
{
*temp_ptr = 0;
diff --git a/board/host/board.h b/board/host/board.h
index f84696d58b..3707e2a1f4 100644
--- a/board/host/board.h
+++ b/board/host/board.h
@@ -36,6 +36,12 @@
#define CONFIG_WP_ACTIVE_HIGH
+/* Module IDs */
+enum module_id {
+ MODULE_I2C,
+ MODULE_UART,
+};
+
enum gpio_signal {
GPIO_EC_INT,
GPIO_LID_OPEN,
diff --git a/board/kirby/board.c b/board/kirby/board.c
index f22bebd44f..169dc420ab 100644
--- a/board/kirby/board.c
+++ b/board/kirby/board.c
@@ -93,6 +93,15 @@ const struct gpio_info gpio_list[] = {
};
BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT);
+/* Pins with alternate functions */
+const struct gpio_alt_func gpio_alt_funcs[] = {
+ {GPIO_C, 0x00e0, GPIO_ALT_TIM3_4, MODULE_LED_KIRBY},
+ {GPIO_A, 0x00f0, GPIO_ALT_SPI, MODULE_SPI},
+ {GPIO_A, 0x0600, GPIO_ALT_USART, MODULE_UART},
+ {GPIO_B, 0x00c0, GPIO_ALT_I2C, MODULE_I2C},
+};
+const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
+
/* Battery temperature ranges in degrees C */
const struct battery_temperature_ranges bat_temp_ranges = {
.start_charging_min_c = 0,
@@ -108,15 +117,3 @@ const struct i2c_port_t i2c_ports[] = {
{"host", I2C_PORT_HOST, 100},
};
BUILD_ASSERT(ARRAY_SIZE(i2c_ports) == I2C_PORTS_USED);
-
-void board_config_post_gpio_init(void)
-{
- /* I2C SCL/SDA on PB6-7 */
- gpio_set_alternate_function(GPIO_B, (1 << 7) | (1 << 6), GPIO_ALT_I2C);
-
- /* USART1 on pins PA9/PA10 */
- gpio_set_alternate_function(GPIO_A, (1 << 9) | (1 << 10),
- GPIO_ALT_USART);
-
- /* TODO: Set TIM3 for PC6-8 here? */
-}
diff --git a/board/kirby/board.h b/board/kirby/board.h
index 5b63b9ce82..2ac8ba6d8b 100644
--- a/board/kirby/board.h
+++ b/board/kirby/board.h
@@ -9,7 +9,6 @@
#define __BOARD_H
/* Optional features */
-#define CONFIG_BOARD_POST_GPIO_INIT
#ifdef HAS_TASK_CHIPSET
#define CONFIG_CHIPSET_GAIA
#endif
@@ -21,6 +20,15 @@
#ifndef __ASSEMBLER__
+/* Module IDs */
+/* TODO(rspangler): use this in place of enum console_channel as well */
+enum module_id {
+ MODULE_I2C,
+ MODULE_LED_KIRBY,
+ MODULE_SPI,
+ MODULE_UART,
+};
+
/* By default, enable all console messages except keyboard */
#define CC_DEFAULT (CC_ALL & ~CC_MASK(CC_KEYSCAN))
diff --git a/board/link/board.c b/board/link/board.c
index cfcc695ecd..1eac758978 100644
--- a/board/link/board.c
+++ b/board/link/board.c
@@ -125,6 +125,25 @@ const struct gpio_info gpio_list[] = {
};
BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT);
+/* Pins with alternate functions */
+const struct gpio_alt_func gpio_alt_funcs[] = {
+ {GPIO_A, 0x03, 1, MODULE_UART}, /* UART0 */
+ {GPIO_A, 0x40, 3, MODULE_I2C}, /* I2C1 SCL */
+ {GPIO_A, 0x80, 3, MODULE_I2C, GPIO_OPEN_DRAIN}, /* I2C1 SDA */
+ {GPIO_B, 0x04, 3, MODULE_I2C}, /* I2C0 SCL */
+ {GPIO_B, 0x08, 3, MODULE_I2C, GPIO_OPEN_DRAIN}, /* I2C0 SDA */
+ {GPIO_B, 0x40, 3, MODULE_I2C}, /* I2C5 SCL */
+ {GPIO_B, 0x80, 3, MODULE_I2C, GPIO_OPEN_DRAIN}, /* I2C5 SDA */
+ {GPIO_C, 0x30, 2, MODULE_UART}, /* UART1 */
+ {GPIO_J, 0x40, 1, MODULE_PECI}, /* PECI Tx */
+ {GPIO_J, 0x80, 0, MODULE_PECI, GPIO_ANALOG}, /* PECI Rx */
+ {GPIO_K, 0x40, 1, MODULE_PWM_KBLIGHT}, /* Fan1 PWM */
+ {GPIO_L, 0x3f, 15, MODULE_LPC}, /* LPC */
+ {GPIO_M, 0x33, 15, MODULE_LPC}, /* LPC */
+ {GPIO_M, 0xc0, 1, MODULE_PWM_FAN}, /* Fan0 PWM/tach */
+};
+const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
+
/* x86 signal list. Must match order of enum x86_signal. */
const struct x86_signal_info x86_signal_list[] = {
{GPIO_PGOOD_5VALW, 1, "PGOOD_5VALW"},
@@ -217,15 +236,6 @@ struct keyboard_scan_config keyscan_config = {
};
/**
- * Configure the GPIOs for the pwm module.
- */
-void configure_fan_gpios(void)
-{
- /* PM6:7 alternate function 1 = channel 0 PWM/tach */
- gpio_set_alternate_function(LM4_GPIO_M, 0xc0, 1);
-}
-
-/**
* Perform necessary actions on host events.
*/
void board_process_wake_events(uint32_t active_wake_events)
@@ -236,12 +246,3 @@ void board_process_wake_events(uint32_t active_wake_events)
else
gpio_set_level(GPIO_PCH_WAKE_L, 1);
}
-
-/**
- * Configure the GPIOs for the pwm module.
- */
-void configure_kblight_gpios(void)
-{
- /* PK6 alternate function 1 = channel 1 PWM */
- gpio_set_alternate_function(LM4_GPIO_K, 0x40, 1);
-}
diff --git a/board/link/board.h b/board/link/board.h
index ea6d2f1f62..c81db98525 100644
--- a/board/link/board.h
+++ b/board/link/board.h
@@ -32,19 +32,30 @@
#define CONFIG_PWM_KBLIGHT
#define CONFIG_TEMP_SENSOR
#define CONFIG_TEMP_SENSOR_TMP006
+#define CONFIG_UART_HOST 1
#define CONFIG_USB_PORT_POWER_SMART
#define CONFIG_WIRELESS
#define CONFIG_WP_ACTIVE_HIGH
#ifndef __ASSEMBLER__
+/* Module IDs */
+/* TODO(rspangler): use this in place of enum console_channel as well */
+enum module_id {
+ MODULE_I2C,
+ MODULE_LPC,
+ MODULE_PECI,
+ MODULE_PWM_FAN,
+ MODULE_PWM_KBLIGHT,
+ MODULE_UART,
+};
+
/* Fan PWM channels */
#define FAN_CH_CPU 0 /* CPU fan */
#define FAN_CH_KBLIGHT 1 /* Keyboard backlight */
#define FAN_CH_POWER_LED 5 /* Power adapter LED */
-enum adc_channel
-{
+enum adc_channel {
/* EC internal die temperature in degrees K. */
ADC_CH_EC_TEMP = 0,
/* Charger current in mA. */
@@ -78,10 +89,6 @@ enum adc_channel
/* USB charge port */
#define USB_CHARGE_PORT_COUNT 2
-/* GPIOs for second UART port */
-#define CONFIG_UART_HOST 1
-#define CONFIG_UART_HOST_GPIOS_PC4_5
-
/* GPIO signal definitions. */
enum gpio_signal {
/* Inputs with interrupt handlers are first for efficiency */
diff --git a/board/mccroskey/board.c b/board/mccroskey/board.c
index 6f76563847..ca38624331 100644
--- a/board/mccroskey/board.c
+++ b/board/mccroskey/board.c
@@ -98,6 +98,15 @@ const struct gpio_info gpio_list[] = {
};
BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT);
+/* Pins with alternate functions */
+const struct gpio_alt_func gpio_alt_funcs[] = {
+ /*
+ * TODO(rspangler): use this instead of hard-coded register writes in
+ * board_config_pre_init().
+ */
+};
+const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
+
void board_config_pre_init(void)
{
uint32_t val;
diff --git a/board/mccroskey/board.h b/board/mccroskey/board.h
index 0501c06ad6..8d2ac274ab 100644
--- a/board/mccroskey/board.h
+++ b/board/mccroskey/board.h
@@ -30,6 +30,13 @@
#ifndef __ASSEMBLER__
+/* Module IDs */
+/* TODO(rspangler): use this in place of enum console_channel as well */
+enum module_id {
+ MODULE_I2C,
+ MODULE_UART,
+};
+
/* By default, enable all console messages except keyboard */
#define CC_DEFAULT (CC_ALL)
diff --git a/board/peppy/board.c b/board/peppy/board.c
index 5a0cc05d5d..623eed7b50 100644
--- a/board/peppy/board.c
+++ b/board/peppy/board.c
@@ -124,6 +124,22 @@ const struct gpio_info gpio_list[] = {
};
BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT);
+/* Pins with alternate functions */
+const struct gpio_alt_func gpio_alt_funcs[] = {
+ {GPIO_A, 0x03, 1, MODULE_UART}, /* UART0 */
+ {GPIO_B, 0x04, 3, MODULE_I2C}, /* I2C0 SCL */
+ {GPIO_B, 0x08, 3, MODULE_I2C, GPIO_OPEN_DRAIN}, /* I2C0 SDA */
+ {GPIO_B, 0x40, 3, MODULE_I2C}, /* I2C5 SCL */
+ {GPIO_B, 0x80, 3, MODULE_I2C, GPIO_OPEN_DRAIN}, /* I2C5 SDA */
+ {GPIO_G, 0x30, 1, MODULE_UART}, /* UART2 */
+ {GPIO_J, 0x40, 1, MODULE_PECI}, /* PECI Tx */
+ {GPIO_J, 0x80, 0, MODULE_PECI, GPIO_ANALOG}, /* PECI Rx */
+ {GPIO_L, 0x3f, 15, MODULE_LPC}, /* LPC */
+ {GPIO_M, 0x33, 15, MODULE_LPC}, /* LPC */
+ {GPIO_N, 0x0c, 1, MODULE_PWM_FAN}, /* Fan0 PWM/tach */
+};
+const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
+
/* x86 signal list. Must match order of enum x86_signal. */
const struct x86_signal_info x86_signal_list[] = {
{GPIO_PP5000_PGOOD, 1, "PGOOD_PP5000"},
@@ -188,15 +204,6 @@ struct keyboard_scan_config keyscan_config = {
};
/**
- * Configure the GPIOs for the pwm module.
- */
-void configure_fan_gpios(void)
-{
- /* PN2:3 alternate function 1 = channel 0 PWM/tach */
- gpio_set_alternate_function(LM4_GPIO_N, 0x0c, 1);
-}
-
-/**
* Perform necessary actions on host wake events.
*/
void board_process_wake_events(uint32_t active_wake_events)
diff --git a/board/peppy/board.h b/board/peppy/board.h
index f8988e507a..db323df3e5 100644
--- a/board/peppy/board.h
+++ b/board/peppy/board.h
@@ -30,11 +30,22 @@
#define CONFIG_PWM_FAN
#define CONFIG_TEMP_SENSOR
#define CONFIG_TEMP_SENSOR_G781
+#define CONFIG_UART_HOST 2
#define CONFIG_USB_PORT_POWER_DUMB
#define CONFIG_WIRELESS
#ifndef __ASSEMBLER__
+/* Module IDs */
+/* TODO(rspangler): use this in place of enum console_channel as well */
+enum module_id {
+ MODULE_I2C,
+ MODULE_LPC,
+ MODULE_PECI,
+ MODULE_PWM_FAN,
+ MODULE_UART,
+};
+
/* PWM channels */
#define FAN_CH_CPU 2 /* CPU fan */
#define FAN_CH_BL_DISPLAY 4 /* LVDS backlight (from PCH, cleaned by EC) */
@@ -56,10 +67,6 @@
/* USB ports */
#define USB_PORT_COUNT 2
-/* GPIOs for second UART port */
-#define CONFIG_UART_HOST 2
-#define CONFIG_UART_HOST_GPIOS_PG4_5
-
/* GPIO signal definitions. */
enum gpio_signal {
/* Inputs with interrupt handlers are first for efficiency */
diff --git a/board/pit/board.c b/board/pit/board.c
index 684e61b1dc..6a5dc07c15 100644
--- a/board/pit/board.c
+++ b/board/pit/board.c
@@ -82,6 +82,15 @@ const struct gpio_info gpio_list[] = {
};
BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT);
+/* Pins with alternate functions */
+const struct gpio_alt_func gpio_alt_funcs[] = {
+ {GPIO_A, 0x0004, GPIO_ALT_TIM2, MODULE_POWER_LED},
+ {GPIO_A, 0x00f0, GPIO_ALT_SPI, MODULE_SPI},
+ {GPIO_A, 0x0600, GPIO_ALT_USART, MODULE_UART},
+ {GPIO_B, 0x0cc0, GPIO_ALT_I2C, MODULE_I2C},
+};
+const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
+
/* Battery temperature ranges in degrees C */
const struct battery_temperature_ranges bat_temp_ranges = {
.start_charging_min_c = 0,
@@ -98,18 +107,6 @@ const struct i2c_port_t i2c_ports[] = {
};
BUILD_ASSERT(ARRAY_SIZE(i2c_ports) == I2C_PORTS_USED);
-void board_config_post_gpio_init(void)
-{
- /* I2C SCL/SDA on PB10-11 and PB6-7 */
- gpio_set_alternate_function(GPIO_B,
- (1 << 11) | (1 << 10) | (1 << 7) | (1 << 6),
- GPIO_ALT_I2C);
-
- /* USART1 on pins PA9/PA10 */
- gpio_set_alternate_function(GPIO_A, (1 << 9) | (1 << 10),
- GPIO_ALT_USART);
-}
-
int pmu_board_init(void)
{
int ver, failure = 0;
diff --git a/board/pit/board.h b/board/pit/board.h
index 0601d91ad2..046849cdc6 100644
--- a/board/pit/board.h
+++ b/board/pit/board.h
@@ -11,7 +11,6 @@
/* Optional features */
#define CONFIG_BATTERY_BQ20Z453
#define CONFIG_BATTERY_SMART
-#define CONFIG_BOARD_POST_GPIO_INIT
#ifdef HAS_TASK_CHARGER
#define CONFIG_CHARGER_TPS65090
#endif
@@ -30,6 +29,15 @@
#ifndef __ASSEMBLER__
+/* Module IDs */
+/* TODO(rspangler): use this in place of enum console_channel as well */
+enum module_id {
+ MODULE_I2C,
+ MODULE_POWER_LED,
+ MODULE_SPI,
+ MODULE_UART,
+};
+
/* By default, enable all console messages except keyboard */
#define CC_DEFAULT (CC_ALL & ~CC_MASK(CC_KEYSCAN))
diff --git a/board/puppy/board.c b/board/puppy/board.c
index 0bb2eb3a6c..be011561ac 100644
--- a/board/puppy/board.c
+++ b/board/puppy/board.c
@@ -82,6 +82,15 @@ const struct gpio_info gpio_list[] = {
};
BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT);
+/* Pins with alternate functions */
+const struct gpio_alt_func gpio_alt_funcs[] = {
+ {GPIO_A, 0x0004, GPIO_ALT_TIM2, MODULE_POWER_LED},
+ {GPIO_A, 0x00f0, GPIO_ALT_SPI, MODULE_SPI},
+ {GPIO_A, 0x0600, GPIO_ALT_USART, MODULE_UART},
+ {GPIO_B, 0x0cc0, GPIO_ALT_I2C, MODULE_I2C},
+};
+const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
+
/* Battery temperature ranges in degrees C */
const struct battery_temperature_ranges bat_temp_ranges = {
.start_charging_min_c = 5,
@@ -98,18 +107,6 @@ const struct i2c_port_t i2c_ports[] = {
};
BUILD_ASSERT(ARRAY_SIZE(i2c_ports) == I2C_PORTS_USED);
-void board_config_post_gpio_init(void)
-{
- /* I2C SCL/SDA on PB10-11 and PB6-7 */
- gpio_set_alternate_function(GPIO_B,
- (1 << 11) | (1 << 10) | (1 << 7) | (1 << 6),
- GPIO_ALT_I2C);
-
- /* USART1 on pins PA9/PA10 */
- gpio_set_alternate_function(GPIO_A, (1 << 9) | (1 << 10),
- GPIO_ALT_USART);
-}
-
int pmu_board_init(void)
{
int ver, failure = 0;
diff --git a/board/puppy/board.h b/board/puppy/board.h
index 024d3ec6d4..8a17472d8c 100644
--- a/board/puppy/board.h
+++ b/board/puppy/board.h
@@ -11,7 +11,6 @@
/* Optional features */
#define CONFIG_BATTERY_BQ20Z453
#define CONFIG_BATTERY_SMART
-#define CONFIG_BOARD_POST_GPIO_INIT
#ifdef HAS_TASK_CHARGER
#define CONFIG_CHARGER_TPS65090
#endif
@@ -29,6 +28,15 @@
#ifndef __ASSEMBLER__
+/* Module IDs */
+/* TODO(rspangler): use this in place of enum console_channel as well */
+enum module_id {
+ MODULE_I2C,
+ MODULE_POWER_LED,
+ MODULE_SPI,
+ MODULE_UART,
+};
+
/* By default, enable all console messages except keyboard */
#define CC_DEFAULT (CC_ALL & ~CC_MASK(CC_KEYSCAN))
diff --git a/board/slippy/board.c b/board/slippy/board.c
index fbeb7e7224..8273ca4e3f 100644
--- a/board/slippy/board.c
+++ b/board/slippy/board.c
@@ -122,6 +122,22 @@ const struct gpio_info gpio_list[] = {
};
BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT);
+/* Pins with alternate functions */
+const struct gpio_alt_func gpio_alt_funcs[] = {
+ {GPIO_A, 0x03, 1, MODULE_UART}, /* UART0 */
+ {GPIO_B, 0x04, 3, MODULE_I2C}, /* I2C0 SCL */
+ {GPIO_B, 0x08, 3, MODULE_I2C, GPIO_OPEN_DRAIN}, /* I2C0 SDA */
+ {GPIO_B, 0x40, 3, MODULE_I2C}, /* I2C5 SCL */
+ {GPIO_B, 0x80, 3, MODULE_I2C, GPIO_OPEN_DRAIN}, /* I2C5 SDA */
+ {GPIO_G, 0x30, 1, MODULE_UART}, /* UART2 */
+ {GPIO_J, 0x40, 1, MODULE_PECI}, /* PECI Tx */
+ {GPIO_J, 0x80, 0, MODULE_PECI, GPIO_ANALOG}, /* PECI Rx */
+ {GPIO_L, 0x3f, 15, MODULE_LPC}, /* LPC */
+ {GPIO_M, 0x33, 15, MODULE_LPC}, /* LPC */
+ {GPIO_N, 0x0c, 1, MODULE_PWM_FAN}, /* Fan0 PWM/tach */
+};
+const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
+
/* x86 signal list. Must match order of enum x86_signal. */
const struct x86_signal_info x86_signal_list[] = {
{GPIO_PP5000_PGOOD, 1, "PGOOD_PP5000"},
@@ -188,15 +204,6 @@ struct keyboard_scan_config keyscan_config = {
};
/**
- * Configure the GPIOs for the pwm module.
- */
-void configure_fan_gpios(void)
-{
- /* PN2:3 alternate function 1 = channel 0 PWM/tach */
- gpio_set_alternate_function(LM4_GPIO_N, 0x0c, 1);
-}
-
-/**
* Perform necessary actions on host wake events.
*/
void board_process_wake_events(uint32_t active_wake_events)
diff --git a/board/slippy/board.h b/board/slippy/board.h
index c8f3d8a38f..aa0cf467e7 100644
--- a/board/slippy/board.h
+++ b/board/slippy/board.h
@@ -31,11 +31,22 @@
#define CONFIG_PWM_FAN
#define CONFIG_TEMP_SENSOR
#define CONFIG_TEMP_SENSOR_G781
+#define CONFIG_UART_HOST 2
#define CONFIG_USB_PORT_POWER_DUMB
#define CONFIG_WIRELESS
#ifndef __ASSEMBLER__
+/* Module IDs */
+/* TODO(rspangler): use this in place of enum console_channel as well */
+enum module_id {
+ MODULE_I2C,
+ MODULE_LPC,
+ MODULE_PECI,
+ MODULE_PWM_FAN,
+ MODULE_UART,
+};
+
/* PWM channels */
#define FAN_CH_CPU 2 /* CPU fan */
#define FAN_CH_BL_DISPLAY 4 /* LVDS backlight (from PCH, cleaned by EC) */
@@ -57,10 +68,6 @@
/* USB ports */
#define USB_PORT_COUNT 2
-/* GPIOs for second UART port */
-#define CONFIG_UART_HOST 2
-#define CONFIG_UART_HOST_GPIOS_PG4_5
-
/* GPIO signal definitions. */
enum gpio_signal {
/* Inputs with interrupt handlers are first for efficiency */
diff --git a/board/snow/board.c b/board/snow/board.c
index 79cacf4e90..55e8012972 100644
--- a/board/snow/board.c
+++ b/board/snow/board.c
@@ -95,6 +95,15 @@ const struct gpio_info gpio_list[] = {
};
BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT);
+/* Pins with alternate functions */
+const struct gpio_alt_func gpio_alt_funcs[] = {
+ /*
+ * TODO(rspangler): use this instead of hard-coded register writes in
+ * board_config_pre_init().
+ */
+};
+const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
+
/* Battery temperature ranges in degrees C */
const struct battery_temperature_ranges bat_temp_ranges = {
.start_charging_min_c = 5,
diff --git a/board/snow/board.h b/board/snow/board.h
index def9540363..1b97b05ebb 100644
--- a/board/snow/board.h
+++ b/board/snow/board.h
@@ -36,6 +36,14 @@
#ifndef __ASSEMBLER__
+/* Module IDs */
+/* TODO(rspangler): use this in place of enum console_channel as well */
+enum module_id {
+ MODULE_I2C,
+ MODULE_POWER_LED,
+ MODULE_UART,
+};
+
/* By default, enable all console messages except keyboard */
#define CC_DEFAULT (CC_ALL & ~CC_MASK(CC_KEYSCAN))
diff --git a/board/spring/board.c b/board/spring/board.c
index fa156d0ae4..44c231ad79 100644
--- a/board/spring/board.c
+++ b/board/spring/board.c
@@ -95,6 +95,15 @@ const struct gpio_info gpio_list[] = {
};
BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT);
+/* Pins with alternate functions */
+const struct gpio_alt_func gpio_alt_funcs[] = {
+ /*
+ * TODO(rspangler): use this instead of hard-coded register writes in
+ * board_config_pre_init().
+ */
+};
+const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
+
/* Battery temperature ranges in degrees C */
const struct battery_temperature_ranges bat_temp_ranges = {
.start_charging_min_c = 5,
diff --git a/board/spring/board.h b/board/spring/board.h
index be9971f85e..6fe6858908 100644
--- a/board/spring/board.h
+++ b/board/spring/board.h
@@ -38,6 +38,13 @@
#ifndef __ASSEMBLER__
+/* Module IDs */
+/* TODO(rspangler): use this in place of enum console_channel as well */
+enum module_id {
+ MODULE_I2C,
+ MODULE_UART,
+};
+
/* By default, enable all console messages except keyboard */
#define CC_DEFAULT (CC_ALL & ~CC_MASK(CC_KEYSCAN))
diff --git a/board/wolf/board.c b/board/wolf/board.c
index fe0db01e86..887ce30cc6 100644
--- a/board/wolf/board.c
+++ b/board/wolf/board.c
@@ -120,6 +120,22 @@ const struct gpio_info gpio_list[] = {
};
BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT);
+/* Pins with alternate functions */
+const struct gpio_alt_func gpio_alt_funcs[] = {
+ {GPIO_A, 0x03, 1, MODULE_UART}, /* UART0 */
+ {GPIO_B, 0x04, 3, MODULE_I2C}, /* I2C0 SCL */
+ {GPIO_B, 0x08, 3, MODULE_I2C, GPIO_OPEN_DRAIN}, /* I2C0 SDA */
+ {GPIO_B, 0x40, 3, MODULE_I2C}, /* I2C5 SCL */
+ {GPIO_B, 0x80, 3, MODULE_I2C, GPIO_OPEN_DRAIN}, /* I2C5 SDA */
+ {GPIO_G, 0x30, 1, MODULE_UART}, /* UART2 */
+ {GPIO_J, 0x40, 1, MODULE_PECI}, /* PECI Tx */
+ {GPIO_J, 0x80, 0, MODULE_PECI, GPIO_ANALOG}, /* PECI Rx */
+ {GPIO_L, 0x3f, 15, MODULE_LPC}, /* LPC */
+ {GPIO_M, 0x33, 15, MODULE_LPC}, /* LPC */
+ {GPIO_N, 0x0c, 1, MODULE_PWM_FAN}, /* Fan0 PWM/tach */
+};
+const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
+
/* x86 signal list. Must match order of enum x86_signal. */
const struct x86_signal_info x86_signal_list[] = {
{GPIO_PP5000_PGOOD, 1, "PGOOD_PP5000"},
@@ -185,15 +201,6 @@ struct keyboard_scan_config keyscan_config = {
};
/**
- * Configure the GPIOs for the pwm module.
- */
-void configure_fan_gpios(void)
-{
- /* PN2:3 alternate function 1 = channel 0 PWM/tach */
- gpio_set_alternate_function(LM4_GPIO_N, 0x0c, 1);
-}
-
-/**
* Perform necessary actions on host wake events.
*/
void board_process_wake_events(uint32_t active_wake_events)
diff --git a/board/wolf/board.h b/board/wolf/board.h
index 22da17b654..7ade111cf0 100644
--- a/board/wolf/board.h
+++ b/board/wolf/board.h
@@ -23,11 +23,22 @@
#define CONFIG_POWER_BUTTON_X86
#define CONFIG_PWM_FAN
#define CONFIG_TEMP_SENSOR
+#define CONFIG_UART_HOST 2
#define CONFIG_USB_PORT_POWER_DUMB
#define CONFIG_WIRELESS
#ifndef __ASSEMBLER__
+/* Module IDs */
+/* TODO(rspangler): use this in place of enum console_channel as well */
+enum module_id {
+ MODULE_I2C,
+ MODULE_LPC,
+ MODULE_PECI,
+ MODULE_PWM_FAN,
+ MODULE_UART,
+};
+
/* PWM channels */
#define FAN_CH_CPU 2 /* CPU fan */
#define FAN_CH_BL_DISPLAY 4 /* LVDS backlight (from PCH, cleaned by EC) */
@@ -49,10 +60,6 @@
/* USB ports */
#define USB_PORT_COUNT 2
-/* GPIOs for second UART port */
-#define CONFIG_UART_HOST 2
-#define CONFIG_UART_HOST_GPIOS_PG4_5
-
/* GPIO signal definitions. */
enum gpio_signal {
/* Inputs with interrupt handlers are first for efficiency */
diff --git a/chip/host/gpio.c b/chip/host/gpio.c
index 64953d7682..975476961c 100644
--- a/chip/host/gpio.c
+++ b/chip/host/gpio.c
@@ -27,3 +27,14 @@ test_mockable int gpio_enable_interrupt(enum gpio_signal signal)
{
return EC_SUCCESS;
}
+
+test_mockable void gpio_set_flags_by_mask(uint32_t port, uint32_t mask,
+ uint32_t flags)
+{
+ /* Nothing */
+}
+
+test_mockable void gpio_set_alternate_function(int port, int mask, int func)
+{
+ /* Nothing */
+}
diff --git a/chip/lm4/gpio.c b/chip/lm4/gpio.c
index ab6423d570..d3a060904d 100644
--- a/chip/lm4/gpio.c
+++ b/chip/lm4/gpio.c
@@ -74,7 +74,6 @@ void gpio_set_alternate_function(int port, int mask, int func)
} else {
LM4_GPIO_AFSEL(port) &= ~mask;
}
- LM4_GPIO_DEN(port) |= mask;
}
test_mockable int gpio_get_level(enum gpio_signal signal)
@@ -93,58 +92,59 @@ void gpio_set_level(enum gpio_signal signal, int value)
gpio_list[signal].mask) = (value ? 0xff : 0);
}
-void gpio_set_flags(enum gpio_signal signal, int flags)
+void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags)
{
- const struct gpio_info *g = gpio_list + signal;
+ /*
+ * Select open drain first, so that we don't glitch the signal
+ * when changing the line to an output.
+ */
+ if (flags & GPIO_OPEN_DRAIN)
+ LM4_GPIO_ODR(port) |= mask;
+ else
+ LM4_GPIO_ODR(port) &= ~mask;
- if (flags & GPIO_OUTPUT) {
- /*
- * Select open drain first, so that we don't glitch the signal
- * when changing the line to an output.
- */
- if (g->flags & GPIO_OPEN_DRAIN)
- LM4_GPIO_ODR(g->port) |= g->mask;
- else
- LM4_GPIO_ODR(g->port) &= ~g->mask;
-
- LM4_GPIO_DIR(g->port) |= g->mask;
-
- /* Set level if necessary */
- if (flags & GPIO_HIGH)
- gpio_set_level(signal, 1);
- else if (flags & GPIO_LOW)
- gpio_set_level(signal, 0);
- } else {
- /* Input */
- LM4_GPIO_DIR(g->port) &= ~g->mask;
- }
+ if (flags & GPIO_OUTPUT)
+ LM4_GPIO_DIR(port) |= mask;
+ else
+ LM4_GPIO_DIR(port) &= ~mask;
/* Handle pullup / pulldown */
- if (g->flags & GPIO_PULL_UP) {
- LM4_GPIO_PUR(g->port) |= g->mask;
- } else if (g->flags & GPIO_PULL_DOWN) {
- LM4_GPIO_PDR(g->port) |= g->mask;
+ if (flags & GPIO_PULL_UP) {
+ LM4_GPIO_PUR(port) |= mask;
+ } else if (flags & GPIO_PULL_DOWN) {
+ LM4_GPIO_PDR(port) |= mask;
} else {
/* No pull up/down */
- LM4_GPIO_PUR(g->port) &= ~g->mask;
- LM4_GPIO_PDR(g->port) &= ~g->mask;
+ LM4_GPIO_PUR(port) &= ~mask;
+ LM4_GPIO_PDR(port) &= ~mask;
}
/* Set up interrupt type */
- if (g->flags & GPIO_INT_LEVEL)
- LM4_GPIO_IS(g->port) |= g->mask;
+ if (flags & GPIO_INT_LEVEL)
+ LM4_GPIO_IS(port) |= mask;
else
- LM4_GPIO_IS(g->port) &= ~g->mask;
+ LM4_GPIO_IS(port) &= ~mask;
- if (g->flags & (GPIO_INT_RISING | GPIO_INT_HIGH))
- LM4_GPIO_IEV(g->port) |= g->mask;
+ if (flags & (GPIO_INT_RISING | GPIO_INT_HIGH))
+ LM4_GPIO_IEV(port) |= mask;
else
- LM4_GPIO_IEV(g->port) &= ~g->mask;
+ LM4_GPIO_IEV(port) &= ~mask;
- if (g->flags & GPIO_INT_BOTH)
- LM4_GPIO_IBE(g->port) |= g->mask;
+ if (flags & GPIO_INT_BOTH)
+ LM4_GPIO_IBE(port) |= mask;
else
- LM4_GPIO_IBE(g->port) &= ~g->mask;
+ LM4_GPIO_IBE(port) &= ~mask;
+
+ if (flags & GPIO_ANALOG)
+ LM4_GPIO_DEN(port) &= ~mask;
+ else
+ LM4_GPIO_DEN(port) |= mask;
+
+ /* Set level */
+ if (flags & GPIO_HIGH)
+ LM4_GPIO_DATA(port, mask) = 0xff;
+ else if (flags & GPIO_LOW)
+ LM4_GPIO_DATA(port, mask) = 0;
}
int gpio_enable_interrupt(enum gpio_signal signal)
@@ -210,7 +210,7 @@ void gpio_pre_init(void)
flags &= ~(GPIO_LOW | GPIO_HIGH);
/* Set up GPIO based on flags */
- gpio_set_flags(i, flags);
+ gpio_set_flags_by_mask(g->port, g->mask, flags);
/* Use as GPIO, not alternate function */
gpio_set_alternate_function(g->port, g->mask, -1);
diff --git a/chip/lm4/i2c.c b/chip/lm4/i2c.c
index abf82f62f4..8fc1591338 100644
--- a/chip/lm4/i2c.c
+++ b/chip/lm4/i2c.c
@@ -236,30 +236,6 @@ exit:
return rv;
}
-/**
- * Configure I2C GPIOs for the module.
- */
-static void configure_i2c_gpios(void)
-{
-#ifdef BOARD_bds
- /* PG6:7 = I2C5 SCL/SDA */
- gpio_set_alternate_function(LM4_GPIO_G, 0xc0, 3);
-
- /* Configure SDA as open-drain. SCL should not be open-drain,
- * since it has an internal pull-up. */
- LM4_GPIO_ODR(LM4_GPIO_G) |= 0x80;
-#else
- /* PA6:7 = I2C1 SCL/SDA; PB2:3 = I2C0 SCL/SDA; PB6:7 = I2C5 SCL/SDA */
- gpio_set_alternate_function(LM4_GPIO_A, 0xc0, 3);
- gpio_set_alternate_function(LM4_GPIO_B, 0xcc, 3);
-
- /* Configure SDA as open-drain. SCL should not be open-drain,
- * since it has an internal pull-up. */
- LM4_GPIO_ODR(LM4_GPIO_A) |= 0x80;
- LM4_GPIO_ODR(LM4_GPIO_B) |= 0x88;
-#endif
-}
-
/*****************************************************************************/
/* Hooks */
@@ -308,7 +284,7 @@ static void i2c_init(void)
clock_wait_cycles(3);
/* Configure GPIOs */
- configure_i2c_gpios();
+ gpio_config_module(MODULE_I2C, 1);
/* No tasks are waiting on ports */
for (i = 0; i < I2C_PORT_COUNT; i++)
diff --git a/chip/lm4/lpc.c b/chip/lm4/lpc.c
index c3cc908ed7..04563caf66 100644
--- a/chip/lm4/lpc.c
+++ b/chip/lm4/lpc.c
@@ -75,20 +75,6 @@ static uint8_t * const cmd_params = (uint8_t *)LPC_POOL_CMD_DATA +
static struct ec_lpc_host_args * const lpc_host_args =
(struct ec_lpc_host_args *)LPC_POOL_CMD_DATA;
-/* Configure GPIOs for module */
-static void configure_gpio(void)
-{
- /*
- * Set digital alternate function 15 for PL0:5, PM0:2, PM4:5 pins.
- *
- * I/O: PL0:3 = command/address/data
- * inp: PL4 (frame), PL5 (reset), PM0 (powerdown), PM5 (clock)
- * out: PM1 (sci), PM4 (serirq)
- */
- gpio_set_alternate_function(LM4_GPIO_L, 0x3f, 0x0f);
- gpio_set_alternate_function(LM4_GPIO_M, 0x33, 0x0f);
-}
-
static void wait_irq_sent(void)
{
/*
@@ -679,7 +665,7 @@ static void lpc_init(void)
LM4_LPC_LPCIRQCTL = 0;
/* Configure GPIOs */
- configure_gpio();
+ gpio_config_module(MODULE_LPC, 1);
/*
* Set LPC channel 0 to I/O address 0x62 (data) / 0x66 (command),
diff --git a/chip/lm4/peci.c b/chip/lm4/peci.c
index b547165b49..b791c97a89 100644
--- a/chip/lm4/peci.c
+++ b/chip/lm4/peci.c
@@ -40,18 +40,6 @@
static int temp_vals[TEMP_AVG_LENGTH];
static int temp_idx = 0;
-/**
- * Configure the GPIOs for the PECI module.
- */
-static void configure_gpios(void)
-{
- /* PJ6 alternate function 1 = PECI Tx */
- gpio_set_alternate_function(LM4_GPIO_J, 0x40, 1);
-
- /* PJ7 analog input = PECI Rx (comparator) */
- LM4_GPIO_DEN(LM4_GPIO_J) &= ~0x80;
-}
-
int peci_get_cpu_temp(void)
{
int v = LM4_PECI_M0D0 & 0xffff;
@@ -120,15 +108,14 @@ DECLARE_HOOK(HOOK_FREQ_CHANGE, peci_freq_changed, HOOK_PRIO_DEFAULT - 1);
static void peci_init(void)
{
- volatile uint32_t scratch __attribute__((unused));
int i;
/* Enable the PECI module and delay a few clocks */
LM4_SYSTEM_RCGCPECI = 1;
- scratch = LM4_SYSTEM_RCGCPECI;
+ clock_wait_cycles(3);
/* Configure GPIOs */
- configure_gpios();
+ gpio_config_module(MODULE_PECI, 1);
/* Set initial clock frequency */
peci_freq_changed();
diff --git a/chip/lm4/pwm_fan.c b/chip/lm4/pwm_fan.c
index 525b9daca2..6309867dae 100644
--- a/chip/lm4/pwm_fan.c
+++ b/chip/lm4/pwm_fan.c
@@ -278,7 +278,7 @@ static void pwm_fan_init(void)
clock_wait_cycles(3);
/* Configure GPIOs */
- configure_fan_gpios();
+ gpio_config_module(MODULE_PWM_FAN, 1);
/* Disable all fans */
LM4_FAN_FANCTL = 0;
diff --git a/chip/lm4/pwm_kblight.c b/chip/lm4/pwm_kblight.c
index df9f965bda..f4628303c9 100644
--- a/chip/lm4/pwm_kblight.c
+++ b/chip/lm4/pwm_kblight.c
@@ -124,7 +124,7 @@ static void pwm_kblight_init(void)
clock_wait_cycles(3);
/* Configure GPIOs */
- configure_kblight_gpios();
+ gpio_config_module(MODULE_PWM_KBLIGHT, 1);
/* Disable all fans */
LM4_FAN_FANCTL = 0;
diff --git a/chip/lm4/registers.h b/chip/lm4/registers.h
index 4185d7ed50..30332d792b 100644
--- a/chip/lm4/registers.h
+++ b/chip/lm4/registers.h
@@ -445,6 +445,23 @@ static inline int lm4_fan_addr(int ch, int offset)
#define LM4_GPIO_AMSEL(port) LM4GPIOREG(port, 0x528)
#define LM4_GPIO_PCTL(port) LM4GPIOREG(port, 0x52c)
+/* Chip-independent aliases for port base addresses */
+#define GPIO_A LM4_GPIO_A
+#define GPIO_B LM4_GPIO_B
+#define GPIO_C LM4_GPIO_C
+#define GPIO_D LM4_GPIO_D
+#define GPIO_E LM4_GPIO_E
+#define GPIO_F LM4_GPIO_F
+#define GPIO_G LM4_GPIO_G
+#define GPIO_H LM4_GPIO_H
+#define GPIO_J LM4_GPIO_J
+#define GPIO_K LM4_GPIO_K
+#define GPIO_L LM4_GPIO_L
+#define GPIO_M LM4_GPIO_M
+#define GPIO_N LM4_GPIO_N
+#define GPIO_P LM4_GPIO_P
+#define GPIO_Q LM4_GPIO_Q
+
/* Value to write to LM4_GPIO_LOCK to unlock writes */
#define LM4_GPIO_LOCK_UNLOCK 0x4c4f434b
diff --git a/chip/lm4/spi.c b/chip/lm4/spi.c
index 7d3b6485d7..6526ded82c 100644
--- a/chip/lm4/spi.c
+++ b/chip/lm4/spi.c
@@ -22,8 +22,7 @@
int spi_enable(int enable)
{
if (enable) {
- /* SSI0 on PA2(CLK), PA4(RX), PA5(TX) alternate function 2 */
- gpio_set_alternate_function(LM4_GPIO_A, 0x34, 2);
+ gpio_config_module(MODULE_SPI, 1);
/* Don't use the SSI0 frame output. CS# is a GPIO so we can
* keep it low during an entire transaction. */
gpio_set_flags(GPIO_SPI_CSn, GPIO_OUTPUT);
@@ -39,8 +38,7 @@ int spi_enable(int enable)
gpio_set_level(GPIO_SPI_CSn, 1);
gpio_set_flags(GPIO_SPI_CSn, GPIO_ODR_HIGH);
- /* PA2,4,5 normal function (high-Z GPIOs) */
- gpio_set_alternate_function(LM4_GPIO_A, 0x34, -1);
+ gpio_config_module(MODULE_SPI, 0);
}
return EC_SUCCESS;
diff --git a/chip/lm4/uart.c b/chip/lm4/uart.c
index 15b83e5551..17443d9848 100644
--- a/chip/lm4/uart.c
+++ b/chip/lm4/uart.c
@@ -139,28 +139,6 @@ static void uart_host_interrupt(void)
/* Must be same prio as LPC interrupt handler so they don't preempt */
DECLARE_IRQ(CONFIG_UART_HOST_IRQ, uart_host_interrupt, 2);
-/**
- * Configure GPIOs for the UART module.
- */
-static void configure_gpio(void)
-{
- /* UART0 RX and TX are GPIO PA0:1 alternate function 1 */
- gpio_set_alternate_function(LM4_GPIO_A, 0x03, 1);
-
-#if (CONFIG_UART_HOST == 1) && defined(CONFIG_UART_HOST_GPIOS_PC4_5)
- /* UART1 RX and TX are GPIO PC4:5 alternate function 2 */
- gpio_set_alternate_function(LM4_GPIO_C, 0x30, 2);
-#elif (CONFIG_UART_HOST == 1) && defined(CONFIG_UART_HOST_GPIOS_PB0_1)
- /* UART1 RX and TX are GPIO PB0:1 alternate function 1 */
- gpio_set_alternate_function(LM4_GPIO_B, 0x03, 1);
-#elif (CONFIG_UART_HOST == 2) && defined(CONFIG_UART_HOST_GPIOS_PG4_5)
- /* UART2 RX and TX are GPIO PG4:5 alternate function 1 */
- gpio_set_alternate_function(LM4_GPIO_G, 0x30, 1);
-#else
-#error "Must put Host UART GPIOs somewhere"
-#endif
-}
-
static void uart_config(int port)
{
/* Disable the port */
@@ -201,8 +179,7 @@ void uart_init(void)
LM4_SYSTEM_RCGCUART |= (1 << CONFIG_UART_HOST) | 1;
scratch = LM4_SYSTEM_RCGCUART;
- /* Configure GPIOs */
- configure_gpio();
+ gpio_config_module(MODULE_UART, 1);
/* Configure UARTs (identically) */
uart_config(0);
diff --git a/chip/stm32/gpio-stm32f.c b/chip/stm32/gpio-stm32f.c
index 5bf3e15ada..0917bd5349 100644
--- a/chip/stm32/gpio-stm32f.c
+++ b/chip/stm32/gpio-stm32f.c
@@ -35,31 +35,30 @@ struct port_config {
/**
* Helper function for generating bitmasks for STM32 GPIO config registers
*/
-static void gpio_config_info(const struct gpio_info *g, uint32_t *addr,
+static void gpio_config_info(uint32_t port, uint32_t mask, uint32_t *addr,
uint32_t *mode, uint32_t *cnf) {
/*
* 2-bit config followed by 2-bit mode for each pin, each
* successive pin raises the exponent for the lowest bit
* set by an order of 4, e.g. 2^0, 2^4, 2^8, etc.
*/
- if (g->mask & 0xff) {
- *addr = g->port; /* GPIOx_CRL */
- *mode = g->mask;
+ if (mask & 0xff) {
+ *addr = port; /* GPIOx_CRL */
+ *mode = mask;
} else {
- *addr = g->port + 0x04; /* GPIOx_CRH */
- *mode = g->mask >> 8;
+ *addr = port + 0x04; /* GPIOx_CRH */
+ *mode = mask >> 8;
}
*mode = *mode * *mode * *mode * *mode;
*mode |= *mode << 1;
*cnf = *mode << 2;
}
-void gpio_set_flags(enum gpio_signal signal, int flags)
+void gpio_set_flags_by_mask(uint32_t port, uint32_t pmask, uint32_t flags)
{
- const struct gpio_info *g = gpio_list + signal;
uint32_t addr, cnf, mode, mask;
- gpio_config_info(g, &addr, &mode, &cnf);
+ gpio_config_info(port, pmask, &addr, &mode, &cnf);
mask = REG32(addr) & ~(cnf | mode);
/*
@@ -80,10 +79,10 @@ void gpio_set_flags(enum gpio_signal signal, int flags)
*/
if (flags & GPIO_PULL_UP) {
mask |= 0x88888888 & cnf;
- gpio_set_level(signal, 1);
+ STM32_GPIO_BSRR(port) = pmask;
} else if (flags & GPIO_PULL_DOWN) {
mask |= 0x88888888 & cnf;
- gpio_set_level(signal, 0);
+ STM32_GPIO_BSRR(port) = pmask << 16;
} else {
mask |= 0x44444444 & cnf;
}
@@ -98,20 +97,25 @@ void gpio_set_flags(enum gpio_signal signal, int flags)
* before it has been configured as such.
*/
if (flags & GPIO_HIGH)
- gpio_set_level(signal, 1);
+ STM32_GPIO_BSRR(port) = pmask;
else if (flags & GPIO_LOW)
- gpio_set_level(signal, 0);
+ STM32_GPIO_BSRR(port) = pmask << 16;
}
/* Set up interrupts if necessary */
ASSERT(!(flags & GPIO_INT_LEVEL));
if (flags & (GPIO_INT_RISING | GPIO_INT_BOTH))
- STM32_EXTI_RTSR |= g->mask;
+ STM32_EXTI_RTSR |= pmask;
if (flags & (GPIO_INT_FALLING | GPIO_INT_BOTH))
- STM32_EXTI_FTSR |= g->mask;
+ STM32_EXTI_FTSR |= pmask;
/* Interrupt is enabled by gpio_enable_interrupt() */
}
+void gpio_set_alternate_function(int port, int mask, int func)
+{
+ /* TODO(rspangler): implement me! */
+}
+
void gpio_pre_init(void)
{
const struct gpio_info *g = gpio_list;
diff --git a/chip/stm32/gpio-stm32l.c b/chip/stm32/gpio-stm32l.c
index 5587625081..22d1350362 100644
--- a/chip/stm32/gpio-stm32l.c
+++ b/chip/stm32/gpio-stm32l.c
@@ -20,30 +20,28 @@
/* For each EXTI bit, record which GPIO entry is using it */
static const struct gpio_info *exti_events[16];
-void gpio_set_flags(enum gpio_signal signal, int flags)
+void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags)
{
- const struct gpio_info *g = gpio_list + signal;
-
/* Bitmask for registers with 2 bits per GPIO pin */
- const uint32_t mask2 = (g->mask * g->mask) | (g->mask * g->mask * 2);
+ const uint32_t mask2 = (mask * mask) | (mask * mask * 2);
uint32_t val;
/* Set up pullup / pulldown */
- val = STM32_GPIO_PUPDR(g->port) & ~mask2;
+ val = STM32_GPIO_PUPDR(port) & ~mask2;
if (flags & GPIO_PULL_UP)
val |= 0x55555555 & mask2; /* Pull Up = 01 */
else if (flags & GPIO_PULL_DOWN)
val |= 0xaaaaaaaa & mask2; /* Pull Down = 10 */
- STM32_GPIO_PUPDR(g->port) = val;
+ STM32_GPIO_PUPDR(port) = val;
/*
* Select open drain first, so that we don't glitch the signal when
* changing the line to an output.
*/
if (flags & GPIO_OPEN_DRAIN)
- STM32_GPIO_OTYPER(g->port) |= g->mask;
+ STM32_GPIO_OTYPER(port) |= mask;
- val = STM32_GPIO_MODER(g->port) & ~mask2;
+ val = STM32_GPIO_MODER(port) & ~mask2;
if (flags & GPIO_OUTPUT) {
/*
* Set pin level first to avoid glitching. This is harmless on
@@ -51,25 +49,25 @@ void gpio_set_flags(enum gpio_signal signal, int flags)
* output drivers until the pin is made an output.
*/
if (flags & GPIO_HIGH)
- gpio_set_level(signal, 1);
+ STM32_GPIO_BSRR(port) = mask;
else if (flags & GPIO_LOW)
- gpio_set_level(signal, 0);
+ STM32_GPIO_BSRR(port) = mask << 16;
/* General purpose, MODE = 01 */
val |= 0x55555555 & mask2;
- STM32_GPIO_MODER(g->port) = val;
+ STM32_GPIO_MODER(port) = val;
} else if (flags & GPIO_INPUT) {
/* Input, MODE=00 */
- STM32_GPIO_MODER(g->port) = val;
+ STM32_GPIO_MODER(port) = val;
}
/* Set up interrupts if necessary */
ASSERT(!(flags & GPIO_INT_LEVEL));
if (flags & (GPIO_INT_RISING | GPIO_INT_BOTH))
- STM32_EXTI_RTSR |= g->mask;
+ STM32_EXTI_RTSR |= mask;
if (flags & (GPIO_INT_FALLING | GPIO_INT_BOTH))
- STM32_EXTI_FTSR |= g->mask;
+ STM32_EXTI_FTSR |= mask;
/* Interrupt is enabled by gpio_enable_interrupt() */
}
@@ -109,7 +107,7 @@ void gpio_pre_init(void)
flags &= ~(GPIO_LOW | GPIO_HIGH);
/* Set up GPIO based on flags */
- gpio_set_flags(i, flags);
+ gpio_set_flags_by_mask(g->port, g->mask, flags);
}
}
diff --git a/chip/stm32/i2c-stm32l.c b/chip/stm32/i2c-stm32l.c
index 28df30fb75..0892dc28e7 100644
--- a/chip/stm32/i2c-stm32l.c
+++ b/chip/stm32/i2c-stm32l.c
@@ -352,6 +352,9 @@ static void i2c_init(void)
}
}
+ /* Configure GPIOs */
+ gpio_config_module(MODULE_I2C, 1);
+
/* Set up initial bus frequencies */
i2c_freq_change();
diff --git a/chip/stm32/power_led.c b/chip/stm32/power_led.c
index 8794c82d7c..237fd14670 100644
--- a/chip/stm32/power_led.c
+++ b/chip/stm32/power_led.c
@@ -65,8 +65,7 @@ static void power_led_use_pwm(void)
val |= 0x00009000; /* alt. function (TIM2/PWM) */
STM32_GPIO_CRL(GPIO_B) = val;
#else
- /* PA2 = TIM2_CH3 */
- gpio_set_alternate_function(GPIO_A, (1 << 2), GPIO_ALT_TIM2);
+ gpio_config_module(MODULE_POWER_LED, 1);
#endif
/* Enable timer */
@@ -123,8 +122,12 @@ static void power_led_manual_off(void)
* configure it as an open-drain output and set it to high impedence,
* but reconfiguring as an input had better results in testing.
*/
+#ifdef BOARD_snow
gpio_set_flags(GPIO_LED_POWER_L, GPIO_INPUT);
gpio_set_level(GPIO_LED_POWER_L, 1);
+#else
+ gpio_config_module(MODULE_POWER_LED, 0);
+#endif
using_pwm = 0;
}
diff --git a/chip/stm32/spi.c b/chip/stm32/spi.c
index 911eeb149c..a646f8143e 100644
--- a/chip/stm32/spi.c
+++ b/chip/stm32/spi.c
@@ -479,7 +479,7 @@ static void spi_chipset_startup(void)
gpio_set_flags(GPIO_SPI1_NSS, GPIO_INT_BOTH | GPIO_PULL_UP);
/* Set SPI pins to alternate function */
- gpio_set_alternate_function(GPIO_A, 0xf0, GPIO_ALT_SPI);
+ gpio_config_module(MODULE_SPI, 1);
/* Set up for next transaction */
setup_for_transaction();
@@ -498,7 +498,7 @@ static void spi_chipset_shutdown(void)
gpio_set_flags(GPIO_SPI1_NSS, 0);
/* Set SPI pins to inputs so we don't leak power when AP is off */
- gpio_set_alternate_function(GPIO_A, 0xf0, -1);
+ gpio_config_module(MODULE_SPI, 0);
}
DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, spi_chipset_shutdown, HOOK_PRIO_DEFAULT);
DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, spi_chipset_shutdown, HOOK_PRIO_DEFAULT);
diff --git a/chip/stm32/uart.c b/chip/stm32/uart.c
index 77b5d93623..dab5231845 100644
--- a/chip/stm32/uart.c
+++ b/chip/stm32/uart.c
@@ -7,6 +7,7 @@
#include "common.h"
#include "clock.h"
+#include "gpio.h"
#include "hooks.h"
#include "registers.h"
#include "task.h"
@@ -146,6 +147,9 @@ void uart_init(void)
STM32_RCC_APB1ENR |= STM32_RCC_PB1_USART ## UARTN;
#endif
+ /* Configure GPIOs */
+ gpio_config_module(MODULE_UART, 1);
+
/*
* UART enabled, 8 Data bits, oversampling x16, no parity,
* RXNE interrupt, TX and RX enabled.
diff --git a/common/gpio_common.c b/common/gpio_common.c
index 11ab9fa4e7..e310814847 100644
--- a/common/gpio_common.c
+++ b/common/gpio_common.c
@@ -61,6 +61,34 @@ static int last_val_changed(int i, int v)
/*****************************************************************************/
/* GPIO API */
+void gpio_config_module(enum module_id id, int enable)
+{
+ const struct gpio_alt_func *af = gpio_alt_funcs;
+ int i;
+
+ /* Set module's pins to alternate functions */
+ for (i = 0; i < gpio_alt_funcs_count; i++, af++) {
+ if (id != af->module_id)
+ continue; /* Pins for some other module */
+
+ if (enable) {
+ gpio_set_flags_by_mask(af->port, af->mask, af->flags);
+ gpio_set_alternate_function(af->port, af->mask,
+ af->func);
+ } else {
+ gpio_set_flags_by_mask(af->port, af->mask, GPIO_INPUT);
+ gpio_set_alternate_function(af->port, af->mask, -1);
+ }
+ }
+}
+
+void gpio_set_flags(enum gpio_signal signal, int flags)
+{
+ const struct gpio_info *g = gpio_list + signal;
+
+ gpio_set_flags_by_mask(g->port, g->mask, flags);
+}
+
const char *gpio_get_name(enum gpio_signal signal)
{
return gpio_list[signal].name;
diff --git a/include/config.h b/include/config.h
index e028319216..1e9173f164 100644
--- a/include/config.h
+++ b/include/config.h
@@ -548,11 +548,6 @@
/* UART index (number) for host UART, if present */
#undef CONFIG_UART_HOST
-/* GPIOs used by host UART. Choose at most one. */
-#undef CONFIG_UART_HOST_GPIOS_PB0_1
-#undef CONFIG_UART_HOST_GPIOS_PC4_5
-#undef CONFIG_UART_HOST_GPIOS_PG4_5
-
/*
* UART transmit buffer size in bytes. Must be a power of 2 for macros in
* common/uart_buffering.c to work properly.
diff --git a/include/gpio.h b/include/gpio.h
index 9517cf40ee..eee7711ee3 100644
--- a/include/gpio.h
+++ b/include/gpio.h
@@ -10,20 +10,24 @@
#include "common.h"
-/* Flag definitions for gpio_info. */
-#define GPIO_INPUT 0x0000 /* Input */
-#define GPIO_OUTPUT 0x0001 /* Output */
-#define GPIO_OPEN_DRAIN 0x0002 /* Output type is open-drain */
-#define GPIO_PULL_UP 0x0004 /* Enable on-chip pullup */
-#define GPIO_PULL_DOWN 0x0008 /* Enable on-chip pulldown */
-#define GPIO_LOW 0x0010 /* If GPIO_OUTPUT, set level low */
-#define GPIO_HIGH 0x0020 /* If GPIO_OUTPUT, set level high */
-#define GPIO_INT_RISING 0x0040 /* Interrupt on rising edge */
-#define GPIO_INT_FALLING 0x0080 /* Interrupt on falling edge */
-#define GPIO_INT_BOTH 0x0100 /* Interrupt on both edges */
-#define GPIO_INT_LOW 0x0200 /* Interrupt on low level */
-#define GPIO_INT_HIGH 0x0400 /* Interrupt on high level */
-#define GPIO_DEFAULT 0x0800 /* Don't set up on boot */
+/* Flag definitions for gpio_info and gpio_alt_func */
+/* The following are valid for both gpio_info and gpio_alt_func: */
+#define GPIO_OPEN_DRAIN (1 << 0) /* Output type is open-drain */
+#define GPIO_PULL_UP (1 << 1) /* Enable on-chip pullup */
+#define GPIO_PULL_DOWN (1 << 2) /* Enable on-chip pulldown */
+/* The following are valid for gpio_alt_func only */
+#define GPIO_ANALOG (1 << 3) /* Set pin to analog-mode */
+/* The following are valid for gpio_info only */
+#define GPIO_INPUT 0 /* Input */
+#define GPIO_OUTPUT (1 << 4) /* Output */
+#define GPIO_LOW (1 << 5) /* If GPIO_OUTPUT, set level low */
+#define GPIO_HIGH (1 << 6) /* If GPIO_OUTPUT, set level high */
+#define GPIO_INT_RISING (1 << 7) /* Interrupt on rising edge */
+#define GPIO_INT_FALLING (1 << 8) /* Interrupt on falling edge */
+#define GPIO_INT_BOTH (1 << 9) /* Interrupt on both edges */
+#define GPIO_INT_LOW (1 << 10) /* Interrupt on low level */
+#define GPIO_INT_HIGH (1 << 11) /* Interrupt on high level */
+#define GPIO_DEFAULT (1 << 12) /* Don't set up on boot */
/* Common flag combinations */
#define GPIO_OUT_LOW (GPIO_OUTPUT | GPIO_LOW)
@@ -37,11 +41,18 @@
/* GPIO signal definition structure, for use by board.c */
struct gpio_info {
+ /* Signal name */
const char *name;
- int port; /* Port (LM4_GPIO_*) */
- int mask; /* Bitmask on that port (0x01 - 0x80; 0x00 =
- * signal not implemented) */
- uint32_t flags; /* Flags (GPIO_*) */
+
+ /* Port base address */
+ uint32_t port;
+
+ /* Bitmask on that port (1 << N; 0 = signal not implemented) */
+ int mask;
+
+ /* Flags (GPIO_*; see above) */
+ uint32_t flags;
+
/*
* Interrupt handler. If non-NULL, and the signal's interrupt is
* enabled, this will be called in the context of the GPIO interrupt
@@ -60,6 +71,27 @@ extern const struct gpio_info gpio_list[];
#define GPIO_SIGNAL_NOT_IMPLEMENTED(name) {name, GPIO_A, 0, 0, NULL}
#endif
+/* GPIO alternate function structure, for use by board.c */
+struct gpio_alt_func {
+ /* Port base address */
+ uint32_t port;
+
+ /* Bitmask on that port (multiple bits allowed) */
+ uint32_t mask;
+
+ /* Alternate function number */
+ int8_t func;
+
+ /* Module ID (as uint8_t, since enum would be 32-bit) */
+ uint8_t module_id;
+
+ /* Flags (GPIO_*; see above). */
+ uint16_t flags;
+};
+
+extern const struct gpio_alt_func gpio_alt_funcs[];
+extern const int gpio_alt_funcs_count;
+
/**
* Pre-initialize GPIOs.
*
@@ -68,6 +100,14 @@ extern const struct gpio_info gpio_list[];
void gpio_pre_init(void);
/**
+ * Configure GPIO pin functions for a module.
+ *
+ * @param id Module ID to initialize
+ * @param enable Enable alternate functions if 1; high-Z pins if 0.
+ */
+void gpio_config_module(enum module_id id, int enable);
+
+/**
* Get the current value of a signal.
*
* @param signal Signal to get
@@ -123,11 +163,28 @@ void gpio_set_level(enum gpio_signal signal, int value);
int gpio_enable_interrupt(enum gpio_signal signal);
/**
+ * Set flags for GPIO(s) by port and mask.
+ *
+ * Use gpio_set_flags() to set flags for an individual GPIO by id.
+ *
+ * Note that modules should usually declare their GPIO alternate functions in
+ * gpio_alt_funcs[] and call gpio_init_module() instead of calling this
+ * directly.
+ *
+ * @param port GPIO port to set (GPIO_*)
+ * @param mask Bitmask of pins on that port to affect
+ * @param flags Flags (GPIO_*; see above)
+ */
+void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags);
+
+/**
* Set alternate function for GPIO(s).
*
- * This is intended for use by other modules' configure_gpio() functions.
+ * Note that modules should usually declare their GPIO alternate functions in
+ * gpio_alt_funcs[] and call gpio_init_module() instead of calling this
+ * directly.
*
- * @param port GPIO port to set (LM4_GPIO_*)
+ * @param port GPIO port to set (GPIO_*)
* @param mask Bitmask of pins on that port to affect
* @param func Alternate function; if <0, configures the specified
* GPIOs for normal GPIO operation.
diff --git a/include/pwm.h b/include/pwm.h
index a4fae7fc75..bb6b5a8549 100644
--- a/include/pwm.h
+++ b/include/pwm.h
@@ -48,11 +48,6 @@ void pwm_set_fan_target_rpm(int rpm);
void pwm_set_fan_duty(int percent);
/**
- * Set up the keyboard gpios.
- */
-void configure_kblight_gpios(void);
-
-/**
* Enable/disable the keyboard backlight.
*/
void pwm_enable_keyboard_backlight(int enable);
@@ -72,9 +67,4 @@ int pwm_get_keyboard_backlight(void);
*/
void pwm_set_keyboard_backlight(int percent);
-/**
- * Configure the GPIOs for the pwm module -- board-specific.
- */
-void configure_fan_gpios(void);
-
#endif /* __CROS_EC_PWM_H */