From 7a5832bcd87c25ed8ed7892b007daae516ff4f32 Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Thu, 26 Jan 2012 15:50:15 -0800 Subject: [PATCH] Fix setting GPIO outputs and keyboard scanning Keyboard scanning was not properly configuring GPIOs on link. Among the problems, it was setting GPIO level then direction, when it needs to set direction first. Also fixed this in gpio pre-init. Signed-off-by: Randall Spangler BUG=chrome-os-partner:7761 TEST=1) press keys on keyboard; see keyboard state change on console 2) 'gpioget PCH_PWRBTNn' should report 1 after boot, not 0 Change-Id: I54010aa6eef1de4822574f964de369b459ee6d0f --- chip/lm4/gpio.c | 4 +++- chip/lm4/keyboard_scan.c | 49 +++++++++++++--------------------------- 2 files changed, 19 insertions(+), 34 deletions(-) diff --git a/chip/lm4/gpio.c b/chip/lm4/gpio.c index 9cc0d30d51..1722105428 100644 --- a/chip/lm4/gpio.c +++ b/chip/lm4/gpio.c @@ -93,8 +93,10 @@ int gpio_pre_init(void) /* Handle GPIO direction */ if (g->flags & GPIO_OUTPUT) { /* Output with default level */ - gpio_set_level(i, g->flags & GPIO_HIGH); LM4_GPIO_DIR(g->port) |= g->mask; + /* Must set level after direction; writes to GPIO_DATA + * before direction is output appear to be ignored. */ + gpio_set_level(i, g->flags & GPIO_HIGH); } else { /* Input */ if (g->flags & GPIO_PULL) { diff --git a/chip/lm4/keyboard_scan.c b/chip/lm4/keyboard_scan.c index cc746697d3..4056f7a21e 100644 --- a/chip/lm4/keyboard_scan.c +++ b/chip/lm4/keyboard_scan.c @@ -80,20 +80,17 @@ static void select_column(int col) LM4_GPIO_DIR(LM4_GPIO_P) = 0xff; LM4_GPIO_DIR(LM4_GPIO_Q) |= 0x1f; LM4_GPIO_DATA(LM4_GPIO_P, 0xff) = 0; - LM4_GPIO_DATA(LM4_GPIO_Q, 0xff) &= ~0x1f; - } else if (col == COLUMN_TRI_STATE_ALL) { - LM4_GPIO_DIR(LM4_GPIO_P) &= ~0xff; - LM4_GPIO_DIR(LM4_GPIO_Q) &= ~0x1f; - } else if (col < 8) { - LM4_GPIO_DIR(LM4_GPIO_P) &= ~0xff; - LM4_GPIO_DIR(LM4_GPIO_Q) &= ~0x1f; - LM4_GPIO_DATA(LM4_GPIO_P, 0xff) = ~(1 << col); - LM4_GPIO_DIR(LM4_GPIO_P) = (1 << col) & 0xff; + LM4_GPIO_DATA(LM4_GPIO_Q, 0x1f) = 0; } else { - LM4_GPIO_DIR(LM4_GPIO_P) &= ~0xff; + LM4_GPIO_DIR(LM4_GPIO_P) = 0; LM4_GPIO_DIR(LM4_GPIO_Q) &= ~0x1f; - LM4_GPIO_DATA(LM4_GPIO_Q, 0xff) = ~(1 << (col - 8)); - LM4_GPIO_DIR(LM4_GPIO_Q) |= 1 << (col - 8); + if (col < 8) { + LM4_GPIO_DIR(LM4_GPIO_P) |= 1 << col; + LM4_GPIO_DATA(LM4_GPIO_P, 1 << col) = 0; + } else if (col != COLUMN_TRI_STATE_ALL) { + LM4_GPIO_DIR(LM4_GPIO_Q) |= 1 << (col - 8); + LM4_GPIO_DATA(LM4_GPIO_Q, 1 << (col - 8)) = 0; + } } #else /* BDS definition */ /* Somehow the col 10 and 11 are swapped on bds. */ @@ -150,18 +147,13 @@ int keyboard_scan_init(void) #endif scratch = LM4_SYSTEM_RCGCGPIO; - /* Clear GPIOAFSEL and enable digital function for PH0:7, - * PK0:3, PN2, PQ0:7. Power button is just a GPIO now. */ + /* Clear GPIOAFSEL and enable digital function for rows */ #ifdef BOARD_link - LM4_GPIO_AFSEL(LM4_GPIO_N) &= 0xff; /* KSI[7:0] */ - LM4_GPIO_DEN(LM4_GPIO_N) |= 0xff; - LM4_GPIO_AFSEL(LM4_GPIO_P) &= 0xff; /* KSO[7:0] */ - LM4_GPIO_DEN(LM4_GPIO_P) |= 0xff; - LM4_GPIO_AFSEL(LM4_GPIO_Q) &= 0x1f; /* KSO[12:8] */ + LM4_GPIO_AFSEL(LM4_GPIO_P) = 0; /* KSO[7:0] */ + LM4_GPIO_DEN(LM4_GPIO_P) = 0xff; + LM4_GPIO_AFSEL(LM4_GPIO_Q) &= ~0x1f; /* KSO[12:8] */ LM4_GPIO_DEN(LM4_GPIO_Q) |= 0x1f; #else - LM4_GPIO_AFSEL(LM4_GPIO_H) = 0; /* KSI[7:0] */ - LM4_GPIO_DEN(LM4_GPIO_H) = 0xff; LM4_GPIO_AFSEL(LM4_GPIO_K) &= ~0x0f; LM4_GPIO_DEN(LM4_GPIO_K) |= 0x0f; LM4_GPIO_AFSEL(LM4_GPIO_N) &= ~0x04; @@ -171,6 +163,8 @@ int keyboard_scan_init(void) #endif /* Set row inputs with pull-up */ + LM4_GPIO_AFSEL(KB_SCAN_ROW_GPIO) &= 0xff; + LM4_GPIO_DEN(KB_SCAN_ROW_GPIO) |= 0xff; LM4_GPIO_DIR(KB_SCAN_ROW_GPIO) = 0; LM4_GPIO_PUR(KB_SCAN_ROW_GPIO) = 0xff; @@ -329,15 +323,4 @@ static void matrix_interrupt(void) task_send_msg(TASK_ID_KEYSCAN, TASK_ID_KEYSCAN, 0); } } - -/* TODO: DECLARE_IRQ stringizing plays poorly with other macros, so need this - * ugly workaround */ -#if (KB_SCAN_ROW_IRQ == LM4_IRQ_GPIOH) -DECLARE_IRQ(LM4_IRQ_GPIOH, matrix_interrupt, 3); -#elif (KB_SCAN_ROW_IRQ == LM4_IRQ_GPION) -DECLARE_IRQ(LM4_IRQ_GPION, matrix_interrupt, 3); -#else -#error "Unsupported KB_SCAN_ROW_IRQ" -/* If you add a board with different GPIO, also make sure supporting code in - * gpio.c is changed so the interrupts don't fight... */ -#endif +DECLARE_IRQ(KB_SCAN_ROW_IRQ, matrix_interrupt, 3);