summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/g/gpio.c151
1 files changed, 151 insertions, 0 deletions
diff --git a/chip/g/gpio.c b/chip/g/gpio.c
index 90e5c4f1c5..6caf0669dd 100644
--- a/chip/g/gpio.c
+++ b/chip/g/gpio.c
@@ -4,6 +4,7 @@
*/
#include "common.h"
+#include "console.h"
#include "gpio.h"
#include "hooks.h"
#include "registers.h"
@@ -277,3 +278,153 @@ void _gpio1_interrupt(void)
}
DECLARE_IRQ(GC_IRQNUM_GPIO0_GPIOCOMBINT, _gpio0_interrupt, 1);
DECLARE_IRQ(GC_IRQNUM_GPIO1_GPIOCOMBINT, _gpio1_interrupt, 1);
+
+static const char * const uart_str[] = {
+ "0_CTS", "0_RTS", "0_RX", "0_TX",
+ "1_CTS", "1_RTS", "1_RX", "1_TX",
+ "2_CTS", "2_RTS", "2_RX", "2_TX",
+};
+
+static void show_pinmux(const char *name, int i, int ofs)
+{
+ uint32_t sel = DIO_SEL_REG(i * 8 + ofs);
+ uint32_t ctl = DIO_CTL_REG(i * 8 + ofs);
+
+ /* skip empty ones (ignoring drive strength bits) */
+ if (sel == 0 && (ctl & (0xf << 2)) == 0)
+ return;
+
+ ccprintf("%08x: %s%d %2d %s%s%s%s",
+ GC_PINMUX_BASE_ADDR + i * 8 + ofs,
+ name, i, sel,
+ (ctl & (1<<2)) ? " IN" : "",
+ (ctl & (1<<3)) ? " PD" : "",
+ (ctl & (1<<4)) ? " PU" : "",
+ (ctl & (1<<5)) ? " INV" : "");
+
+ if (sel >= 1 && sel <= 16)
+ ccprintf(" GPIO0_GPIO%d\n", sel - 1);
+ else if (sel >= 17 && sel <= 32)
+ ccprintf(" GPIO1_GPIO%d\n", sel - 17);
+ else if (sel >= 67 && sel <= 78)
+ ccprintf(" UART%s\n", uart_str[sel - 67]);
+ else
+ ccprintf("\n");
+}
+
+static void print_dio_str(uint32_t sel)
+{
+ if (sel >= 1 && sel <= 2)
+ ccprintf(" VIO%d\n", 2 - sel);
+ else if (sel >= 3 && sel <= 10)
+ ccprintf(" DIOB%d\n", 10 - sel);
+ else if (sel >= 11 && sel <= 25)
+ ccprintf(" DIOA%d\n", 25 - sel);
+ else if (sel >= 26 && sel <= 30)
+ ccprintf(" DIOM%d\n", 30 - sel);
+ else
+ ccprintf("\n");
+}
+
+static void show_pinmux_gpio(const char *name, int i, int ofs)
+{
+ uint32_t sel = DIO_SEL_REG(i * 4 + ofs);
+
+ if (sel == 0)
+ return;
+
+ ccprintf("%08x: %s%d %2d",
+ GC_PINMUX_BASE_ADDR + i * 4 + ofs,
+ name, i, sel);
+ print_dio_str(sel);
+}
+
+static void show_pinmux_uart(int i)
+{
+
+ uint32_t ofs = GC_PINMUX_UART0_CTS_SEL_OFFSET + i * 4;
+ uint32_t sel = DIO_SEL_REG(ofs);
+
+ if (sel == 0)
+ return;
+
+ ccprintf("%08x: UART%s %2d",
+ GC_PINMUX_BASE_ADDR + ofs,
+ uart_str[i], sel);
+
+ print_dio_str(sel);
+}
+
+static int command_pinmux(int argc, char **argv)
+{
+ int i;
+
+ /* Pad sources */
+ for (i = 0; i <= 4; i++)
+ show_pinmux("DIOM", i, 0x00);
+ for (i = 0; i <= 14; i++)
+ show_pinmux("DIOA", i, 0x28);
+ for (i = 0; i <= 7; i++)
+ show_pinmux("DIOB", i, 0xa0);
+
+ ccprintf("\n");
+
+ /* GPIO & Peripheral sources */
+ for (i = 0; i <= 15; i++)
+ show_pinmux_gpio("GPIO0_GPIO", i, 0xf8);
+ for (i = 0; i <= 15; i++)
+ show_pinmux_gpio("GPIO1_GPIO", i, 0x134);
+
+ for (i = 0; i <= 11; i++)
+ show_pinmux_uart(i);
+
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(pinmux, command_pinmux,
+ "",
+ "Display pinmux info",
+ NULL);
+
+static const char * const int_str[] = {
+ "LOW", "FALLING", "HIGH", "RISING",
+};
+
+static void show_gpiocfg(int n)
+{
+ uint32_t din = GR_GPIO_DATAIN(n);
+ uint32_t dout = GR_GPIO_DOUT(n);
+ uint32_t outen = GR_GPIO_SETDOUTEN(n);
+ uint32_t inten = GR_GPIO_SETINTEN(n);
+ uint32_t intpol = GR_GPIO_SETINTPOL(n);
+ uint32_t inttype = GR_GPIO_SETINTTYPE(n);
+ uint32_t mask;
+ int i, j;
+
+ for (i = 0, mask = 0x1; i < 16; i++, mask <<= 1) {
+ /* Skip it unless it's an output or an interrupt */
+ if (!((outen & mask) || (inten & mask)))
+ continue;
+
+ ccprintf("GPIO%d_GPIO%d:\tread %d", n, i, !!(din & mask));
+ if (outen & mask)
+ ccprintf(" drive %d", !!(dout & mask));
+ if (inten & mask) {
+ j = ((intpol & mask) ? 2 : 0) +
+ ((inttype & mask) ? 1 : 0);
+ ccprintf(" INT_%s", int_str[j]);
+ }
+ ccprintf("\n");
+ }
+}
+
+static int command_gpiocfg(int argc, char **argv)
+{
+ show_gpiocfg(0);
+ show_gpiocfg(1);
+
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(gpiocfg, command_gpiocfg,
+ "",
+ "Display GPIO configs",
+ NULL);