From 0f9bf2587eae7334957f6fe0efded9a34e2fa67b Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Sat, 6 Feb 2010 12:15:27 +0900 Subject: [PATCH] s5pc110: Fix keypad codes Signed-off-by: Joonyoung Shim --- board/samsung/universal/universal.c | 91 ++++++++++++++++++----------------- include/asm-arm/arch-s5pc1xx/keypad.h | 4 ++ 2 files changed, 52 insertions(+), 43 deletions(-) diff --git a/board/samsung/universal/universal.c b/board/samsung/universal/universal.c index 4d87618..4118dfc 100644 --- a/board/samsung/universal/universal.c +++ b/board/samsung/universal/universal.c @@ -787,9 +787,12 @@ static void setup_media_gpios(void) static void check_keypad(void) { unsigned int reg, value; - unsigned int col_mask, row_mask; + unsigned int col_num, row_num; + unsigned int col_mask; + unsigned int col_mask_shift; + unsigned int row_state[4]; + unsigned int i; unsigned int auto_download = 0; - unsigned int col_value[4], i; if (machine_is_wmg160()) return; @@ -798,6 +801,9 @@ static void check_keypad(void) struct s5pc100_gpio *gpio = (struct s5pc100_gpio *)S5PC100_GPIO_BASE; + row_num = 3; + col_num = 3; + /* Set GPH2[2:0] to KP_COL[2:0] */ gpio_cfg_pin(&gpio->gpio_h2, 0, 0x3); gpio_cfg_pin(&gpio->gpio_h2, 1, 0x3); @@ -809,64 +815,63 @@ static void check_keypad(void) gpio_cfg_pin(&gpio->gpio_h3, 2, 0x3); reg = S5PC100_KEYPAD_BASE; + col_mask = S5PC1XX_KEYIFCOL_MASK; + col_mask_shift = 0; } else { if (board_is_limo_real() || board_is_limo_universal()) { - row_mask = 0x00FF; - col_mask = 0x0FFF; + row_num = 2; + col_num = 3; } else { - row_mask = 0xFFFF; - col_mask = 0xFFFF; + row_num = 4; + col_num = 4; } - for (i = 0; i < 4; i++) { + for (i = 0; i < row_num; i++) { /* Set GPH3[3:0] to KP_ROW[3:0] */ - if (row_mask & (0xF << (i << 2))) { - gpio_cfg_pin(&s5pc110_gpio->gpio_h3, i, 0x3); - gpio_set_pull(&s5pc110_gpio->gpio_h3, i, - GPIO_PULL_UP); - } + gpio_cfg_pin(&s5pc110_gpio->gpio_h3, i, 0x3); + gpio_set_pull(&s5pc110_gpio->gpio_h3, i, GPIO_PULL_UP); + } + for (i = 0; i < col_num; i++) /* Set GPH2[3:0] to KP_COL[3:0] */ - if (col_mask & (0xF << (i << 2))) - gpio_cfg_pin(&s5pc110_gpio->gpio_h2, i, 0x3); - } + gpio_cfg_pin(&s5pc110_gpio->gpio_h2, i, 0x3); reg = S5PC110_KEYPAD_BASE; + col_mask = S5PC110_KEYIFCOLEN_MASK; + col_mask_shift = 8; } - /* init col */ - value = 0x00; - writel(value, reg + S5PC1XX_KEYIFCOL_OFFSET); - value = readl(reg + S5PC1XX_KEYIFROW_OFFSET); - /* VOLUMEDOWN and CAM(Half shot) Button */ - if ((value & KBR1) == 0) { - i = 0; - while (i < 4) { - value = readl(reg + S5PC1XX_KEYIFCOL_OFFSET); - value |= 0xff; - value &= ~(1 << i); - writel(value, reg + S5PC1XX_KEYIFCOL_OFFSET); - udelay(10*1000); - col_value[i++] = readl(reg + S5PC1XX_KEYIFROW_OFFSET); - } - writel(0x00, reg + S5PC1XX_KEYIFCOL_OFFSET); - printf("%s[%d] col_value 0x%x, 0x%x, 0x%x\n", __func__, __LINE__, col_value[0], col_value[1], col_value[2]); - /* expected value is row_value[0] = 0x00 row_value[1] = 0x01 */ - /* workaround */ - if (col_value[1] == 0xd && col_value[2] == 0xe && machine_is_geminus()) - auto_download = 1; + /* KEYIFCOL reg clear */ + writel(0, reg + S5PC1XX_KEYIFCOL_OFFSET); - /* Workaround for aquila */ - if ((col_value[0] & 0x3) == 0x3 && (col_value[1] & 0x3) == 0x0) - auto_download = 1; + /* key_scan */ + for (i = 0; i < col_num; i++) { + value = col_mask; + value &= ~(1 << i) << col_mask_shift; - if ((col_value[0] & 0x3) == 0x3 && (col_value[1] & 0x3) == 0x3) - auto_download = 1; + writel(value, reg + S5PC1XX_KEYIFCOL_OFFSET); + udelay(1000); - if ((col_value[0] & 0x3) == 0x3 && (col_value[1] & 0x3) != 0x3) - display_info = 1; + value = readl(reg + S5PC1XX_KEYIFROW_OFFSET); + row_state[i] = ~value & ((1 << row_num) - 1); + printf("[%d col] row_state: 0x%x\n", i, row_state[i]); } + /* KEYIFCOL reg clear */ + writel(0, reg + S5PC1XX_KEYIFCOL_OFFSET); + + if (machine_is_aquila) { + /* cam full shot & volume down */ + if ((row_state[0] & 0x1) && (row_state[1] & 0x2)) + auto_download = 1; + /* volume down */ + else if ((row_state[1] & 0x2)) + display_info = 1; + } else if (machine_is_geminus()) + /* volume down & home */ + if ((row_state[1] & 0x2) && (row_state[2] & 0x1)) + auto_download = 1; + if (auto_download) setenv("bootcmd", "usbdown"); } diff --git a/include/asm-arm/arch-s5pc1xx/keypad.h b/include/asm-arm/arch-s5pc1xx/keypad.h index 97aafb0..c907ff9 100644 --- a/include/asm-arm/arch-s5pc1xx/keypad.h +++ b/include/asm-arm/arch-s5pc1xx/keypad.h @@ -31,4 +31,8 @@ #define S5PC1XX_KEYIFROW_OFFSET (0x0C) #define S5PC1XX_KEYIFFC_OFFSET (0x10) +/* KEYIFCOL */ +#define S5PC1XX_KEYIFCOL_MASK (0xff << 0) +#define S5PC110_KEYIFCOLEN_MASK (0xff << 8) + #endif -- 2.7.4