change source file mode to 0644 instead of 0755
[profile/mobile/platform/kernel/u-boot-tm1.git] / arch / arm / cpu / armv7 / sc8830 / eic.c
1 /*
2  *  linux/arch/arm/mach-sprd/gpio.c
3  *
4  *  Generic SPRD GPIO handling
5  *
6  *  Author:     Yingchun Li(yingchun.li@spreadtrum.com)
7  *  Created:    March 10, 2010
8  *  Copyright:  Spreadtrum Inc.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License version 2 as
12  *  published by the Free Software Foundation.
13  */
14 #include <asm/io.h>
15 #include <asm/arch/sprd_reg.h>
16 #include <asm/arch/sci_types.h>
17 #include <asm/arch/sprd_eic.h>
18 #include <asm/arch/adi_hal_internal.h>
19 #include <asm/arch/chip_drv_common_io.h>
20 #include <asm/arch/regs_adi.h>
21
22 #define KERN_WARNING ""
23 #define WARN(nmu, fmt...) printf(fmt)
24 #define WARN_ON(num)
25 #define BUG_ON(__cond__) if(__cond__) printf("%s line: %d bug on\n", __FUNCTION__, __LINE__)
26 #define pr_err(fmt...) printf(fmt)
27 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
28 #define pr_debug(fmt...) printf(fmt)
29
30 //#define DEBUG
31
32
33 #ifdef DEBUG
34 #define GPIO_DBG(fmt...) pr_debug(fmt)
35 #else
36 #define GPIO_DBG(fmt...)
37 #endif
38
39 struct eic_info{
40         u32 base_addr;
41         int die;
42         u8  bit_num;
43 };
44
45 enum eic_die {
46         A_DIE = 0,
47         D_DIE = 1,
48 };
49
50 #define GPIO_INVALID_ID (0xffff)
51 #define INVALID_REG     (~(u32)0)
52
53 #define EIC_DATA 0x00
54 #define EIC_MASK 0x04
55 #define EIC_IEV  0x14
56 #define EIC_IE   0x18
57 #define EIC_RIS  0x1C
58 #define EIC_MIS  0x20
59 #define EIC_IC   0x24
60 #define EIC_TRIG 0x28
61
62 #define EIC0_CTL 0x40
63 #define EIC1_CTL 0x44
64 #define EIC2_CTL 0x48
65 #define EIC3_CTL 0x4C
66 #define EIC4_CTL 0x50
67 #define EIC5_CTL 0x54
68 #define EIC6_CTL 0x58
69 #define EIC7_CTL 0x5C
70 #if defined(CONFIG_ADIE_SC2723S)||defined(CONFIG_ADIE_SC2723)
71 #define EIC8_CTL 0x60
72 #define EIC9_CTL 0x64
73 #define EIC10_CTL 0x68
74 #endif
75
76
77 static void __get_eic_base_info (u32 eic_id, struct eic_info *info)
78 {
79         int i = 0;
80         u32 table_size = 0;
81         struct gpio_section  *section_table;
82
83         if (eic_id>=SPRD_ADIE_EIC_START && eic_id<=SPRD_ADIE_EIC_END)
84         {
85                 info->base_addr= SPRD_ANA_EIC_PHYS;
86                 #if defined(CONFIG_ADIE_SC2723S)||defined(CONFIG_ADIE_SC2723)
87                 info->bit_num  = eic_id&0xF;
88                 #else
89                 info->bit_num  = eic_id&0x7;
90                 #endif
91                 info->die          = A_DIE;
92
93         }
94         else if (eic_id>=SPRD_DDIE_EIC_START && eic_id<=SPRD_DDIE_EIC_END)
95         {
96                 info->base_addr= SPRD_EIC_PHYS+0x80;
97                 info->bit_num  = eic_id&0x7;
98                 info->die          = D_DIE;
99         }
100         else
101         {
102                 info->base_addr = INVALID_REG;
103         }
104 }
105
106 static int __eic_get_pin_data (struct eic_info *info)
107 {
108         u32 offset_addr = 0;
109         u32 reg_addr = 0, reg_data;
110
111         if (info->base_addr == INVALID_REG)
112         {
113                 return  -1;
114         }
115
116         reg_addr = info->base_addr + EIC_DATA;
117
118         if (info->die == D_DIE)
119                 reg_data = __raw_readl (reg_addr);
120         else
121                 reg_data = ANA_REG_GET (reg_addr);
122         reg_data &= 1<<info->bit_num;
123
124         return reg_data;
125 }
126
127 static int __eic_get_data_mask (struct eic_info *info)
128 {
129         u32 offset_addr = 0;
130         u32 reg_addr = 0, reg_data;
131
132         if (info->base_addr == INVALID_REG)
133         {
134                 return  -1;
135         }
136
137         reg_addr = info->base_addr + EIC_MASK;
138
139         if (info->die == D_DIE)
140                 reg_data = __raw_readl (reg_addr);
141         else
142                 reg_data = ANA_REG_GET (reg_addr);
143         reg_data &= 1<<info->bit_num;
144
145         return reg_data;
146 }
147
148 /*
149         set data mask, the gpio data register can be access
150  */
151 static void __eic_set_data_mask (struct eic_info *info, int b_on)
152 {
153         u32 offset_addr = 0;
154         u32 reg_addr = 0, reg_data;
155
156         reg_addr = info->base_addr + EIC_MASK;
157
158         if (info->base_addr == INVALID_REG)
159         {
160                 return;
161         }
162
163         if (info->die == D_DIE)
164                 reg_data = __raw_readl (reg_addr);
165         else
166                 reg_data = ANA_REG_GET (reg_addr);
167
168         if (b_on)
169         {
170                 if (!(reg_data&(1<<info->bit_num)))
171                 {
172                         reg_data |= 1<<info->bit_num;
173                         if (info->die == D_DIE)
174                                 __raw_writel (reg_addr, reg_data);
175                         else
176                                 ANA_REG_SET (reg_addr, reg_data);
177                 }
178         }
179         else
180         {
181                 if (reg_data&(1<<info->bit_num))
182                 {
183                         reg_data &= ~(1<<info->bit_num);
184                         if (info->die == D_DIE)
185                                 __raw_writel (reg_addr, reg_data);
186                         else
187                                 ANA_REG_SET (reg_addr, reg_data);
188                 }
189         }
190 }
191
192 int sprd_eic_get(unsigned offset)
193 {
194         unsigned eic_id = offset;
195         struct eic_info gpio_info;
196
197         __get_eic_base_info (eic_id, &gpio_info);
198
199         if (!__eic_get_data_mask (&gpio_info)) {
200                 WARN(1, "GPIO_%d data mask hasn't been opened!\n", eic_id);
201         }
202
203         return __eic_get_pin_data (&gpio_info);
204 }
205
206 int sprd_eic_irq_set_type(unsigned offset, unsigned flow_type)
207 {
208         return 0;
209 }
210
211 int sprd_eic_irq_sts(unsigned offset)
212 {
213         return 0;
214 }
215
216 int sprd_eic_request(unsigned offset)
217 {
218         unsigned eic_id = offset;
219         struct eic_info gpio_info;
220
221         __get_eic_base_info (eic_id, &gpio_info);
222         __eic_set_data_mask (&gpio_info, 1);
223         return 0;
224 }
225
226 static void sprd_eic_free(unsigned offset)
227 {
228         unsigned eic_id = offset;
229         struct eic_info gpio_info;
230
231         __get_eic_base_info (eic_id, &gpio_info);
232         __eic_set_data_mask (&gpio_info, 0);
233         return;
234 }
235
236 void sprd_eic_init(void)
237 {
238         REG32(REG_AON_APB_APB_EB0) |= BIT_EIC_EB;
239         REG32(REG_AON_APB_APB_RTC_EB) |= BIT_EIC_RTC_EB|BIT_EIC_RTCDV5_EB;
240         ANA_REG_OR(ANA_REG_GLB_ARM_MODULE_EN, BIT_ANA_EIC_EN);
241         ANA_REG_OR(ANA_REG_GLB_RTC_CLK_EN,    BIT_RTC_EIC_EN);
242 }
243
244 int get_volumn_down_status2()
245 {
246         int temp_cnt = 600;
247         int status = 0;
248
249         ANA_REG_SET(ADI_EIC_MASK, 0xffff);
250         udelay(3000);
251
252         do {
253                 temp_cnt --;
254
255                 status = ANA_REG_GET(ADI_EIC_DATA);
256                 status = status & (1 << 10);
257         } while(temp_cnt > 0);
258
259         return status;
260 }