tizen 2.4 release
[profile/mobile/platform/kernel/u-boot-tm1.git] / board / spreadtrum / sp7715ga / sprd_kp.c
1 #include <common.h>
2 #include <malloc.h>
3 #include "key_map.h"
4 #include <boot_mode.h>
5 #include <asm/arch/mfp.h>
6 #include <asm/arch/sprd_keypad.h>
7 #include <asm/arch/chip_drv_common_io.h>
8
9
10 #define mdelay(_ms) udelay(_ms*1000)
11 struct key_map_info * sprd_key_map = 0;
12
13 void board_keypad_init(void)
14 {
15     unsigned int key_type;
16
17     sprd_key_map = malloc(sizeof(struct key_map_info));
18
19     if(NULL == sprd_key_map){
20       printf("%s malloc faild\n", __FUNCTION__);
21       return;
22     }
23
24     sprd_key_map->total_size = ARRAY_SIZE(board_key_map);
25     sprd_key_map->keycode_size = sizeof(board_key_map[0])*2;
26     sprd_key_map->key_map = board_key_map;
27     sprd_key_map->total_row = CONFIG_KEYPAD_ROW_CNT;
28     sprd_key_map->total_col = CONFIG_KEYPAD_COL_CNT;
29
30     if(sprd_key_map->total_size % sprd_key_map->keycode_size){
31         printf("%s: board_key_map config error, it should be %d aligned\n", __FUNCTION__, sprd_key_map->keycode_size);
32         return;
33     }
34
35     /* init sprd keypad controller */
36     REG32(REG_AON_APB_APB_EB0) |= BIT_8;
37     REG32(REG_AON_APB_APB_RTC_EB) |= BIT_1;
38     REG32(REG_AON_APB_APB_RST0) |= BIT_8;
39     udelay(2000);
40      REG32(REG_AON_APB_APB_RST0) &= ~BIT_8;
41
42     REG_KPD_INT_CLR = KPD_INT_ALL;
43     REG_KPD_POLARITY = CFG_ROW_POLARITY | CFG_COL_POLARITY;
44     REG_KPD_CLK_DIV_CNT = CFG_CLK_DIV & KPDCLK0_CLK_DIV0;
45     REG_KPD_LONG_KEY_CNT = CONFIG_KEYPAD_LONG_CNT;
46     REG_KPD_DEBOUNCE_CNT = CONFIG_KEYPAD_DEBOUNCE_CNT;//0x8;0x13
47     REG_KPD_CTRL  = (7<<8)/*Col0-Col2 Enable*/|(7<<16)/*Row0-Row2 Enable*/;
48     REG_KPD_CTRL |= 1; /*Keypad Enable*/;
49 }
50
51 static char handle_scan_code(unsigned char scan_code)
52 {
53     int cnt;
54     int key_map_cnt;
55     unsigned char * key_map;
56     int pos = 0;
57
58     if(NULL == sprd_key_map){
59         printf("plase call board_keypad_init first\n");
60         return 0;
61     }
62
63     key_map_cnt = sprd_key_map->total_size / sprd_key_map->keycode_size;
64     key_map = sprd_key_map->key_map;
65 #ifdef KEYPAD_DEBUG
66     printf("scan code %d\n", scan_code);
67 #endif
68     for(cnt = 0; cnt<key_map_cnt; cnt++){
69         pos = cnt * 2;
70         if(key_map[pos] == scan_code)
71           return key_map[pos + 1];
72     }
73     return 0;
74 }
75
76 //it can only handle one key now
77 unsigned char board_key_scan(void)
78 {
79     uint32_t s_int_status = REG_KPD_INT_RAW_STATUS;
80     uint32_t s_key_status = REG_KPD_KEY_STATUS;
81     uint32_t scan_code = 0;
82     uint32_t key_code =0;
83 #ifdef KEYPAD_DEBUG
84         printf("key operation flags is %08x, key %08x\n", REG_KPD_INT_RAW_STATUS, REG_KPD_KEY_STATUS);
85 #endif
86     mdelay(50);
87     if((s_int_status & KPD_PRESS_INT0) || (s_int_status & KPD_LONG_KEY_INT0)){
88         scan_code = s_key_status & (KPD1_ROW_CNT | KPD1_COL_CNT);
89         key_code += handle_scan_code(scan_code);
90     } if((s_int_status & KPD_PRESS_INT1) || (s_int_status & KPD_LONG_KEY_INT1)){
91         scan_code = (s_key_status & (KPD2_ROW_CNT | KPD2_COL_CNT))>>8;
92         key_code += handle_scan_code(scan_code);
93     }if((s_int_status & KPD_PRESS_INT2) || (s_int_status & KPD_LONG_KEY_INT2)){
94         scan_code = (s_key_status & (KPD3_ROW_CNT | KPD3_COL_CNT))>>16;
95         key_code += handle_scan_code(scan_code);
96     }if((s_int_status & KPD_PRESS_INT3) || (s_int_status & KPD_LONG_KEY_INT3)){
97         scan_code = (s_key_status & (KPD4_ROW_CNT | KPD4_COL_CNT))>>24;
98         key_code += handle_scan_code(scan_code);
99     }
100
101     if(s_int_status)
102         REG_KPD_INT_CLR = KPD_INT_ALL;
103     return key_code;
104 }
105
106 unsigned int check_key_boot(unsigned char key)
107 {
108     if(KEY_VOLUMEUP == key)
109       return BOOT_CALIBRATE;
110     else if(KEY_HOME == key)
111       return BOOT_FASTBOOT;
112     else if(KEY_VOLUMEDOWN== key)
113       return BOOT_RECOVERY;
114     else 
115       return 0;
116 }