Merge branch 'for-linus' of git://git.o-hand.com/linux-rpurdie-backlight
[pandora-kernel.git] / arch / arm / mach-w90x900 / mfp.c
1 /*
2  * linux/arch/arm/mach-w90x900/mfp.c
3  *
4  * Copyright (c) 2008 Nuvoton technology corporation
5  *
6  * Wan ZongShun <mcuos.com@gmail.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation;version 2 of the License.
11  */
12
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/device.h>
16 #include <linux/list.h>
17 #include <linux/errno.h>
18 #include <linux/err.h>
19 #include <linux/string.h>
20 #include <linux/clk.h>
21 #include <linux/mutex.h>
22 #include <linux/io.h>
23
24 #include <mach/hardware.h>
25
26 #define REG_MFSEL       (W90X900_VA_GCR + 0xC)
27
28 #define GPSELF          (0x01 << 1)
29
30 #define GPSELC          (0x03 << 2)
31 #define ENKPI           (0x02 << 2)
32 #define ENNAND          (0x01 << 2)
33
34 #define GPSELEI0        (0x01 << 26)
35 #define GPSELEI1        (0x01 << 27)
36
37 #define GPIOG0TO1       (0x03 << 14)
38 #define GPIOG2TO3       (0x03 << 16)
39 #define ENSPI           (0x0a << 14)
40 #define ENI2C0          (0x01 << 14)
41 #define ENI2C1          (0x01 << 16)
42
43 static DEFINE_MUTEX(mfp_mutex);
44
45 void mfp_set_groupf(struct device *dev)
46 {
47         unsigned long mfpen;
48         const char *dev_id;
49
50         BUG_ON(!dev);
51
52         mutex_lock(&mfp_mutex);
53
54         dev_id = dev_name(dev);
55
56         mfpen = __raw_readl(REG_MFSEL);
57
58         if (strcmp(dev_id, "nuc900-emc") == 0)
59                 mfpen |= GPSELF;/*enable mac*/
60         else
61                 mfpen &= ~GPSELF;/*GPIOF[9:0]*/
62
63         __raw_writel(mfpen, REG_MFSEL);
64
65         mutex_unlock(&mfp_mutex);
66 }
67 EXPORT_SYMBOL(mfp_set_groupf);
68
69 void mfp_set_groupc(struct device *dev)
70 {
71         unsigned long mfpen;
72         const char *dev_id;
73
74         BUG_ON(!dev);
75
76         mutex_lock(&mfp_mutex);
77
78         dev_id = dev_name(dev);
79
80         mfpen = __raw_readl(REG_MFSEL);
81
82         if (strcmp(dev_id, "nuc900-lcd") == 0)
83                 mfpen |= GPSELC;/*enable lcd*/
84         else if (strcmp(dev_id, "nuc900-kpi") == 0) {
85                 mfpen &= (~GPSELC);/*enable kpi*/
86                 mfpen |= ENKPI;
87         } else if (strcmp(dev_id, "nuc900-nand") == 0) {
88                 mfpen &= (~GPSELC);/*enable nand*/
89                 mfpen |= ENNAND;
90         } else
91                 mfpen &= (~GPSELC);/*GPIOC[14:0]*/
92
93         __raw_writel(mfpen, REG_MFSEL);
94
95         mutex_unlock(&mfp_mutex);
96 }
97 EXPORT_SYMBOL(mfp_set_groupc);
98
99 void mfp_set_groupi(struct device *dev)
100 {
101         unsigned long mfpen;
102         const char *dev_id;
103
104         BUG_ON(!dev);
105
106         mutex_lock(&mfp_mutex);
107
108         dev_id = dev_name(dev);
109
110         mfpen = __raw_readl(REG_MFSEL);
111
112         mfpen &= ~GPSELEI1;/*default gpio16*/
113
114         if (strcmp(dev_id, "nuc900-wdog") == 0)
115                 mfpen |= GPSELEI1;/*enable wdog*/
116         else if (strcmp(dev_id, "nuc900-atapi") == 0)
117                 mfpen |= GPSELEI0;/*enable atapi*/
118         else if (strcmp(dev_id, "nuc900-keypad") == 0)
119                 mfpen &= ~GPSELEI0;/*enable keypad*/
120
121         __raw_writel(mfpen, REG_MFSEL);
122
123         mutex_unlock(&mfp_mutex);
124 }
125 EXPORT_SYMBOL(mfp_set_groupi);
126
127 void mfp_set_groupg(struct device *dev)
128 {
129         unsigned long mfpen;
130         const char *dev_id;
131
132         BUG_ON(!dev);
133
134         mutex_lock(&mfp_mutex);
135
136         dev_id = dev_name(dev);
137
138         mfpen = __raw_readl(REG_MFSEL);
139
140         if (strcmp(dev_id, "nuc900-spi") == 0) {
141                 mfpen &= ~(GPIOG0TO1 | GPIOG2TO3);
142                 mfpen |= ENSPI;/*enable spi*/
143         } else if (strcmp(dev_id, "nuc900-i2c0") == 0) {
144                 mfpen &= ~(GPIOG0TO1);
145                 mfpen |= ENI2C0;/*enable i2c0*/
146         } else if (strcmp(dev_id, "nuc900-i2c1") == 0) {
147                 mfpen &= ~(GPIOG2TO3);
148                 mfpen |= ENI2C1;/*enable i2c1*/
149         } else {
150                 mfpen &= ~(GPIOG0TO1 | GPIOG2TO3);/*GPIOG[3:0]*/
151         }
152
153         __raw_writel(mfpen, REG_MFSEL);
154
155         mutex_unlock(&mfp_mutex);
156 }
157 EXPORT_SYMBOL(mfp_set_groupg);
158