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