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;
86 static char handle_scan_code(unsigned char scan_code)
90 unsigned char * key_map;
93 if(NULL == sprd_key_map){
94 printf("plase call board_keypad_init first\n");
98 key_map_cnt = sprd_key_map->total_size / sprd_key_map->keycode_size;
99 key_map = sprd_key_map->key_map;
101 printf("scan code %d\n", scan_code);
103 for(cnt = 0; cnt<key_map_cnt; cnt++){
105 if(key_map[pos] == scan_code)
106 return key_map[pos + 1];
111 //it can only handle one key now
112 unsigned char board_key_scan(void)
114 uint32_t s_int_status = REG_KPD_INT_RAW_STATUS;
115 uint32_t s_key_status = REG_KPD_KEY_STATUS;
116 uint32_t scan_code = 0;
117 uint32_t key_code =0;
119 if((s_int_status & KPD_PRESS_INT0) || (s_int_status & KPD_LONG_KEY_INT0)){
120 scan_code = s_key_status & (KPD1_ROW_CNT | KPD1_COL_CNT);
121 key_code = handle_scan_code(scan_code);
122 }else if((s_int_status & KPD_PRESS_INT1) || (s_int_status & KPD_LONG_KEY_INT1)){
123 scan_code = (s_key_status & (KPD2_ROW_CNT | KPD2_COL_CNT))>>8;
124 key_code = handle_scan_code(scan_code);
125 }else if((s_int_status & KPD_PRESS_INT2) || (s_int_status & KPD_LONG_KEY_INT2)){
126 scan_code = (s_key_status & (KPD3_ROW_CNT | KPD3_COL_CNT))>>16;
127 key_code = handle_scan_code(scan_code);
128 }else if((s_int_status & KPD_PRESS_INT3) || (s_int_status & KPD_LONG_KEY_INT3)){
129 scan_code = (s_key_status & (KPD4_ROW_CNT | KPD4_COL_CNT))>>24;
130 key_code = handle_scan_code(scan_code);
134 REG_KPD_INT_CLR = KPD_INT_ALL;
138 unsigned int check_key_boot(unsigned char key)
141 return BOOT_CALIBRATE;
142 else if(KEY_HOME == key)
143 return BOOT_FASTBOOT;
144 else if(KEY_BACK == key)
145 return BOOT_RECOVERY;
146 else if(KEY_VOLUMEUP== key)