1
2
3
4
5
6
7
8#include <common.h>
9#include <asm/io.h>
10#include <asm/gpio.h>
11
12#define CON_MASK(x) (0xf << ((x) << 2))
13#define CON_SFR(x, v) ((v) << ((x) << 2))
14
15#define DAT_MASK(x) (0x1 << (x))
16#define DAT_SET(x) (0x1 << (x))
17
18#define PULL_MASK(x) (0x3 << ((x) << 1))
19#define PULL_MODE(x, v) ((v) << ((x) << 1))
20
21#define DRV_MASK(x) (0x3 << ((x) << 1))
22#define DRV_SET(x, m) ((m) << ((x) << 1))
23#define RATE_MASK(x) (0x1 << (x + 16))
24#define RATE_SET(x) (0x1 << (x + 16))
25
26void s5p_gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg)
27{
28 unsigned int value;
29
30 value = readl(&bank->con);
31 value &= ~CON_MASK(gpio);
32 value |= CON_SFR(gpio, cfg);
33 writel(value, &bank->con);
34}
35
36void s5p_gpio_direction_output(struct s5p_gpio_bank *bank, int gpio, int en)
37{
38 s5p_gpio_cfg_pin(bank, gpio, GPIO_OUTPUT);
39 s5p_gpio_set_value(bank, gpio, en);
40}
41
42void s5p_gpio_direction_input(struct s5p_gpio_bank *bank, int gpio)
43{
44 s5p_gpio_cfg_pin(bank, gpio, GPIO_INPUT);
45}
46
47void s5p_gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int en)
48{
49 unsigned int value;
50
51 value = readl(&bank->dat);
52 value &= ~DAT_MASK(gpio);
53 if (en)
54 value |= DAT_SET(gpio);
55 writel(value, &bank->dat);
56}
57
58unsigned int s5p_gpio_get_value(struct s5p_gpio_bank *bank, int gpio)
59{
60 unsigned int value;
61
62 value = readl(&bank->dat);
63 return !!(value & DAT_MASK(gpio));
64}
65
66void s5p_gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode)
67{
68 unsigned int value;
69
70 value = readl(&bank->pull);
71 value &= ~PULL_MASK(gpio);
72
73 switch (mode) {
74 case GPIO_PULL_DOWN:
75 case GPIO_PULL_UP:
76 value |= PULL_MODE(gpio, mode);
77 break;
78 default:
79 break;
80 }
81
82 writel(value, &bank->pull);
83}
84
85void s5p_gpio_set_drv(struct s5p_gpio_bank *bank, int gpio, int mode)
86{
87 unsigned int value;
88
89 value = readl(&bank->drv);
90 value &= ~DRV_MASK(gpio);
91
92 switch (mode) {
93 case GPIO_DRV_1X:
94 case GPIO_DRV_2X:
95 case GPIO_DRV_3X:
96 case GPIO_DRV_4X:
97 value |= DRV_SET(gpio, mode);
98 break;
99 default:
100 return;
101 }
102
103 writel(value, &bank->drv);
104}
105
106void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode)
107{
108 unsigned int value;
109
110 value = readl(&bank->drv);
111 value &= ~RATE_MASK(gpio);
112
113 switch (mode) {
114 case GPIO_DRV_FAST:
115 case GPIO_DRV_SLOW:
116 value |= RATE_SET(gpio);
117 break;
118 default:
119 return;
120 }
121
122 writel(value, &bank->drv);
123}
124
125struct s5p_gpio_bank *s5p_gpio_get_bank(unsigned gpio)
126{
127 int bank;
128 unsigned g = gpio - s5p_gpio_part_max(gpio);
129
130 bank = g / GPIO_PER_BANK;
131 bank *= sizeof(struct s5p_gpio_bank);
132 return (struct s5p_gpio_bank *) (s5p_gpio_base(gpio) + bank);
133}
134
135int s5p_gpio_get_pin(unsigned gpio)
136{
137 return gpio % GPIO_PER_BANK;
138}
139
140
141
142int gpio_request(unsigned gpio, const char *label)
143{
144 return 0;
145}
146
147int gpio_free(unsigned gpio)
148{
149 return 0;
150}
151
152int gpio_direction_input(unsigned gpio)
153{
154 s5p_gpio_direction_input(s5p_gpio_get_bank(gpio),
155 s5p_gpio_get_pin(gpio));
156 return 0;
157}
158
159int gpio_direction_output(unsigned gpio, int value)
160{
161 s5p_gpio_direction_output(s5p_gpio_get_bank(gpio),
162 s5p_gpio_get_pin(gpio), value);
163 return 0;
164}
165
166int gpio_get_value(unsigned gpio)
167{
168 return (int) s5p_gpio_get_value(s5p_gpio_get_bank(gpio),
169 s5p_gpio_get_pin(gpio));
170}
171
172int gpio_set_value(unsigned gpio, int value)
173{
174 s5p_gpio_set_value(s5p_gpio_get_bank(gpio),
175 s5p_gpio_get_pin(gpio), value);
176
177 return 0;
178}
179