2 * linux/arch/arm/mach-sprd/gpio.c
4 * Generic SPRD GPIO handling
6 * Author: Yingchun Li(yingchun.li@spreadtrum.com)
7 * Created: March 10, 2010
8 * Copyright: Spreadtrum Inc.
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.
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>
22 #define KERN_WARNING ""
23 #define WARN(nmu, fmt...) printf(fmt)
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)
34 #define GPIO_DBG(fmt...) pr_debug(fmt)
36 #define GPIO_DBG(fmt...)
50 #define GPIO_INVALID_ID (0xffff)
51 #define INVALID_REG (~(u32)0)
70 #if defined(CONFIG_ADIE_SC2723S)||defined(CONFIG_ADIE_SC2723)
73 #define EIC10_CTL 0x68
77 static void __get_eic_base_info (u32 eic_id, struct eic_info *info)
81 struct gpio_section *section_table;
83 if (eic_id>=SPRD_ADIE_EIC_START && eic_id<=SPRD_ADIE_EIC_END)
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;
89 info->bit_num = eic_id&0x7;
94 else if (eic_id>=SPRD_DDIE_EIC_START && eic_id<=SPRD_DDIE_EIC_END)
96 info->base_addr= SPRD_EIC_PHYS+0x80;
97 info->bit_num = eic_id&0x7;
102 info->base_addr = INVALID_REG;
106 static int __eic_get_pin_data (struct eic_info *info)
109 u32 reg_addr = 0, reg_data;
111 if (info->base_addr == INVALID_REG)
116 reg_addr = info->base_addr + EIC_DATA;
118 if (info->die == D_DIE)
119 reg_data = __raw_readl (reg_addr);
121 reg_data = ANA_REG_GET (reg_addr);
122 reg_data &= 1<<info->bit_num;
127 static int __eic_get_data_mask (struct eic_info *info)
130 u32 reg_addr = 0, reg_data;
132 if (info->base_addr == INVALID_REG)
137 reg_addr = info->base_addr + EIC_MASK;
139 if (info->die == D_DIE)
140 reg_data = __raw_readl (reg_addr);
142 reg_data = ANA_REG_GET (reg_addr);
143 reg_data &= 1<<info->bit_num;
149 set data mask, the gpio data register can be access
151 static void __eic_set_data_mask (struct eic_info *info, int b_on)
154 u32 reg_addr = 0, reg_data;
156 reg_addr = info->base_addr + EIC_MASK;
158 if (info->base_addr == INVALID_REG)
163 if (info->die == D_DIE)
164 reg_data = __raw_readl (reg_addr);
166 reg_data = ANA_REG_GET (reg_addr);
170 if (!(reg_data&(1<<info->bit_num)))
172 reg_data |= 1<<info->bit_num;
173 if (info->die == D_DIE)
174 __raw_writel (reg_addr, reg_data);
176 ANA_REG_SET (reg_addr, reg_data);
181 if (reg_data&(1<<info->bit_num))
183 reg_data &= ~(1<<info->bit_num);
184 if (info->die == D_DIE)
185 __raw_writel (reg_addr, reg_data);
187 ANA_REG_SET (reg_addr, reg_data);
192 int sprd_eic_get(unsigned offset)
194 unsigned eic_id = offset;
195 struct eic_info gpio_info;
197 __get_eic_base_info (eic_id, &gpio_info);
199 if (!__eic_get_data_mask (&gpio_info)) {
200 WARN(1, "GPIO_%d data mask hasn't been opened!\n", eic_id);
203 return __eic_get_pin_data (&gpio_info);
206 int sprd_eic_irq_set_type(unsigned offset, unsigned flow_type)
211 int sprd_eic_irq_sts(unsigned offset)
216 int sprd_eic_request(unsigned offset)
218 unsigned eic_id = offset;
219 struct eic_info gpio_info;
221 __get_eic_base_info (eic_id, &gpio_info);
222 __eic_set_data_mask (&gpio_info, 1);
226 static void sprd_eic_free(unsigned offset)
228 unsigned eic_id = offset;
229 struct eic_info gpio_info;
231 __get_eic_base_info (eic_id, &gpio_info);
232 __eic_set_data_mask (&gpio_info, 0);
236 void sprd_eic_init(void)
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);
244 int get_volumn_down_status2()
249 ANA_REG_SET(ADI_EIC_MASK, 0xffff);
255 status = ANA_REG_GET(ADI_EIC_DATA);
256 status = status & (1 << 10);
257 } while(temp_cnt > 0);