]> git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/gpio/s5p_gpio.c
Merge branch 'u-boot-pxa/master' into 'u-boot-arm/master'
[people/ms/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 }