tizen 2.4 release
[profile/mobile/platform/kernel/u-boot-tm1.git] / arch / arm / cpu / armv7 / tiger / mfp_sprd.c
1 /*
2  *  linux/arch/arm/mach-sc8800s/mfp-sprd.c
3  *
4  *  Spreadtrum SoC multi-function pin configuration support
5  *
6  *  The GPIOs on SoC can be configured as one of many alternate
7  *  functions,
8  *
9  *  Author:     Yingchun Li(yingchun.li@spreadtrum.com)
10  *  Created:    March 10, 2010
11  *  Copyright:  Spreadtrum Inc.
12  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License version 2 as
15  *  published by the Free Software Foundation.
16 */
17 //#define DEBUG
18
19 //#include <linux/module.h>
20 //#include <linux/kernel.h>
21 //#include <asm/io.h>
22 //#include <mach/mfp.h>
23 //#include <mach/regs_cpc.h>
24 #include <asm/arch/mfp.h>
25 #include <asm/arch/sc8810_reg_base.h>
26 #include <asm/arch/sc8810_cpc.h>
27 #include <asm/io.h>
28
29 /*
30 NOTE: pin to gpio's map, you should check it from your chip's spec
31         carefully.
32         in the map table, pin as the index, for mostly we use
33         MFP_PIN_TO_GPIO to get the gpio from the pin
34
35 const static unsigned long pin_gpio_map[MFP_PIN_MAX] = {
36         [MFP_PIN_MAX - 1] = 0xffff
37 };
38
39 */
40
41 /*
42         we cann't find a easy way to map pin to gpio, so drop it.
43 */
44 unsigned long mfp_to_gpio(int pin)
45 {
46         BUG_ON(1);
47 }
48
49 static  int __mfp_validate(unsigned long c)
50 {
51         return 1;
52 }
53
54 static unsigned long __mfp_get_pin_reg(int pin_offset)
55 {
56         if (!(pin_offset & A_DIE_PIN)) {
57                 return (unsigned long)PIN_CTL_BASE + pin_offset;
58         } else {
59                 pin_offset &= ~A_DIE_PIN;
60                 return (unsigned long)ANA_PIN_CTL_BASE + pin_offset;
61         }
62 }
63
64 #ifdef DEBUG
65 #define MFP_DBG(fmt...) pr_debug(fmt)
66 static unsigned long __mfp_get_physical(int pin_offset)
67 {
68         if (!(pin_offset & A_DIE_PIN)) {
69                 return (unsigned long)SPRD_CPC_PHYS + pin_offset;
70         } else {
71                 pin_offset &= ~A_DIE_PIN;
72                 return (unsigned long)SPRD_MISC_PHYS + 0x180 + pin_offset;
73         }
74 }
75 #else
76 #define MFP_DBG(fmt...)
77 #endif
78
79 static int __mfp_config_pin(unsigned long c)
80 {
81         unsigned long flags;
82         unsigned long pin_reg;
83         unsigned long pin_cfg;
84         int pin_offset;
85
86         pin_offset = MFP_CFG_TO_REG_OFFS(c);
87         pin_reg = __mfp_get_pin_reg(pin_offset);
88
89         MFP_DBG("register is :0x%x, old config is %x\r\n",
90                 __mfp_get_physical(pin_offset),
91                 __raw_readl(pin_reg));
92
93         //local_irq_save(flags);
94         pin_cfg =__raw_readl(pin_reg);
95         if (c & MFP_IO_SET) {
96                 pin_cfg = (pin_cfg & ~MFP_IO_MASK) | (c & MFP_IO_MASK);
97         }
98
99         if (c & MFP_S_PULL_SET) {
100                 pin_cfg = (pin_cfg & ~MFP_S_PULL_MASK) | (c & MFP_S_PULL_MASK);
101         }
102
103         if (c & MFP_AF_SET) {
104                 pin_cfg = (pin_cfg & ~MFP_AF_MASK) | (c & MFP_AF_MASK);
105         }
106
107         if (c & MFP_F_PULL_SET) {
108                 pin_cfg = (pin_cfg & ~MFP_F_PULL_MASK) | (c & MFP_F_PULL_MASK);
109         }
110
111         if (c & MFP_DS_SET) {
112                 pin_cfg = (pin_cfg & ~MFP_DS_MASK) | (c & MFP_DS_MASK);
113         }
114
115         __raw_writel(pin_cfg, pin_reg);
116 //      local_irq_restore(flags);
117
118         MFP_DBG("new config is :%x\r\n", (int)pin_cfg);
119
120         return 0;
121 }
122
123 static unsigned long spi_cs1_gpio_cfg = MFP_CFG_X(SPI_CSN0, GPIO, DS1, F_PULL_NONE, S_PULL_DOWN, IO_NONE);
124
125 void sprd_mfp_config(unsigned long *mfp_cfgs, int num)
126 {
127         unsigned long flags;
128         unsigned long *c;
129         int res;
130         int i;
131
132         for (i = 0, c = mfp_cfgs; i < num; i++, c++) {
133
134                 res = __mfp_validate((*c));
135                 if (res < 0)
136                         continue;
137
138         //      local_irq_save(flags);
139
140                 __mfp_config_pin(*c);
141
142         //      local_irq_restore(flags);
143         }
144 }
145 //EXPORT_SYMBOL_GPL(sprd_mfp_config);