5 #include <asm/arch/sc8810_keypad.h>
7 #error "no keypad definition file included"
9 #include <asm/arch/mfp.h>
10 #include <boot_mode.h>
12 struct key_map_info * sprd_key_map = 0;
14 static unsigned long keypad_func_cfg[] = {
15 MFP_CFG_X(KEYOUT0, AF0, DS1, F_PULL_NONE, S_PULL_NONE, IO_OE),
16 MFP_CFG_X(KEYOUT1, AF0, DS1, F_PULL_NONE, S_PULL_NONE, IO_OE),
17 MFP_CFG_X(KEYOUT2, AF0, DS1, F_PULL_NONE, S_PULL_NONE, IO_OE),
18 MFP_CFG_X(KEYOUT3, AF0, DS1, F_PULL_NONE, S_PULL_NONE, IO_OE),
19 MFP_CFG_X(KEYOUT4, AF0, DS1, F_PULL_NONE, S_PULL_NONE, IO_OE),
20 MFP_CFG_X(KEYOUT5, AF0, DS1, F_PULL_NONE, S_PULL_NONE, IO_OE),
21 MFP_CFG_X(KEYOUT6, AF0, DS1, F_PULL_NONE, S_PULL_NONE, IO_OE),
22 MFP_CFG_X(KEYOUT7, AF0, DS1, F_PULL_NONE, S_PULL_NONE, IO_OE),
23 MFP_CFG_X(KEYIN0, AF0, DS1, F_PULL_UP, S_PULL_UP, IO_IE),
24 MFP_CFG_X(KEYIN1, AF0, DS1, F_PULL_UP, S_PULL_UP, IO_IE),
25 MFP_CFG_X(KEYIN2, AF0, DS1, F_PULL_UP, S_PULL_UP, IO_IE),
26 MFP_CFG_X(KEYIN3, AF0, DS1, F_PULL_UP, S_PULL_UP, IO_IE),
27 MFP_CFG_X(KEYIN4, AF0, DS1, F_PULL_UP, S_PULL_UP, IO_IE),
28 MFP_CFG_X(KEYIN5, AF0, DS1, F_PULL_UP, S_PULL_UP, IO_IE),
29 MFP_CFG_X(KEYIN6, AF0, DS1, F_PULL_UP, S_PULL_UP, IO_IE),
30 MFP_CFG_X(KEYIN7, AF0, DS1, F_PULL_UP, S_PULL_UP, IO_IE),
33 static void sprd_config_keypad_pins(void)
35 sprd_mfp_config(keypad_func_cfg, ARRAY_SIZE(keypad_func_cfg));
38 void board_keypad_init(void)
40 unsigned int key_type;
42 sprd_key_map = malloc(sizeof(struct key_map_info));
44 if(NULL == sprd_key_map){
45 printf("%s malloc faild\n", __FUNCTION__);
49 sprd_key_map->total_size = ARRAY_SIZE(board_key_map);
50 sprd_key_map->keycode_size = sizeof(board_key_map[0])*2;
51 sprd_key_map->key_map = board_key_map;
52 sprd_key_map->total_row = CONFIG_KEYPAD_ROW_CNT;
53 sprd_key_map->total_col = CONFIG_KEYPAD_COL_CNT;
55 if(sprd_key_map->total_size % sprd_key_map->keycode_size){
56 printf("%s: board_key_map config error, it should be %d aligned\n", __FUNCTION__, sprd_key_map->keycode_size);
60 /* init sprd keypad controller */
61 REG_INT_DIS = (1 << IRQ_KPD_INT);
62 REG_GR_GEN0 |= BIT_8 | BIT_26;
63 sprd_config_keypad_pins();
64 REG_KPD_INT_CLR = KPD_INT_ALL;
65 REG_KPD_POLARITY = CFG_ROW_POLARITY | CFG_COL_POLARITY;
66 REG_KPD_CLK_DIV_CNT = CFG_CLK_DIV & KPDCLK0_CLK_DIV0;
67 REG_KPD_LONG_KEY_CNT = CONFIG_KEYPAD_LONG_CNT;
68 REG_KPD_DEBOUNCE_CNT = CONFIG_KEYPAD_DEBOUNCE_CNT;//0x8;0x13
69 key_type = ((((~(0xffffffff << (sprd_key_map->total_col - KPD_COL_MIN_NUM))) << 20) | ((~(0xffffffff << (sprd_key_map->total_row- KPD_ROW_MIN_NUM))) << 16)) & (KPDCTL_ROW | KPDCTL_COL));
70 REG_KPD_CTRL = 0x7 | key_type;
72 //open all press & release & long key operation flags
73 REG_KPD_INT_EN = KPD_INT_ALL;
76 if(REG_KPD_INT_RAW_STATUS){
77 printf("key operation flags is %08x, key %08x\n", REG_KPD_INT_RAW_STATUS, REG_KPD_KEY_STATUS);
79 REG_KPD_INT_CLR = KPD_INT_ALL;
84 REG_GR_GEN0 |= (BIT_9 | BIT_24);//EIC_EN,RTC_EIC_EN
85 printf("GEN0 %x\n", REG_GR_GEN0);
89 static char handle_scan_code(unsigned char scan_code)
93 unsigned char * key_map;
96 if(NULL == sprd_key_map){
97 printf("plase call board_keypad_init first\n");
101 key_map_cnt = sprd_key_map->total_size / sprd_key_map->keycode_size;
102 key_map = sprd_key_map->key_map;
104 printf("scan code %d\n", scan_code);
106 for(cnt = 0; cnt<key_map_cnt; cnt++){
108 if(key_map[pos] == scan_code)
109 return key_map[pos + 1];
114 //it can only handle one key now
115 unsigned char board_key_scan(void)
117 uint32_t s_int_status = REG_KPD_INT_RAW_STATUS;
118 uint32_t s_key_status = REG_KPD_KEY_STATUS;
119 uint32_t scan_code = 0;
120 uint32_t key_code =0;
122 printf("key operation flags is %08x, key %08x\n", REG_KPD_INT_RAW_STATUS, REG_KPD_KEY_STATUS);
124 if((s_int_status & KPD_PRESS_INT0) || (s_int_status & KPD_LONG_KEY_INT0)){
125 scan_code = s_key_status & (KPD1_ROW_CNT | KPD1_COL_CNT);
126 key_code = handle_scan_code(scan_code);
127 }else if((s_int_status & KPD_PRESS_INT1) || (s_int_status & KPD_LONG_KEY_INT1)){
128 scan_code = (s_key_status & (KPD2_ROW_CNT | KPD2_COL_CNT))>>8;
129 key_code = handle_scan_code(scan_code);
130 }else if((s_int_status & KPD_PRESS_INT2) || (s_int_status & KPD_LONG_KEY_INT2)){
131 scan_code = (s_key_status & (KPD3_ROW_CNT | KPD3_COL_CNT))>>16;
132 key_code = handle_scan_code(scan_code);
133 }else if((s_int_status & KPD_PRESS_INT3) || (s_int_status & KPD_LONG_KEY_INT3)){
134 scan_code = (s_key_status & (KPD4_ROW_CNT | KPD4_COL_CNT))>>24;
135 key_code = handle_scan_code(scan_code);
139 REG_KPD_INT_CLR = KPD_INT_ALL;
143 unsigned int check_key_boot(unsigned char key)
146 return BOOT_CALIBRATE;
147 else if(KEY_HOME == key)
148 return BOOT_FASTBOOT;
149 else if(KEY_BACK == key)
150 return BOOT_RECOVERY;
151 else if(KEY_VOLUMEUP== key)