]> git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/gpio/s5p_gpio.c
Merge branch 'master' of git://www.denx.de/git/u-boot-cfi-flash
[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 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
26 void 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
36 void 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
42 void s5p_gpio_direction_input(struct s5p_gpio_bank *bank, int gpio)
43 {
44 s5p_gpio_cfg_pin(bank, gpio, GPIO_INPUT);
45 }
46
47 void 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
58 unsigned 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
66 void 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
85 void 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
106 void 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
125 struct 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
135 int s5p_gpio_get_pin(unsigned gpio)
136 {
137 return gpio % GPIO_PER_BANK;
138 }
139
140 /* Common GPIO API */
141
142 int gpio_request(unsigned gpio, const char *label)
143 {
144 return 0;
145 }
146
147 int gpio_free(unsigned gpio)
148 {
149 return 0;
150 }
151
152 int 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
159 int 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
166 int 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
172 int 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 }