]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
1f8f7730 SG |
2 | /* |
3 | * (C) Copyright 2015 Google, Inc | |
4 | * | |
5 | * (C) Copyright 2008-2014 Rockchip Electronics | |
6 | * Peter, Software Engineering, <[email protected]>. | |
1f8f7730 SG |
7 | */ |
8 | ||
9 | #include <common.h> | |
10 | #include <dm.h> | |
48647828 | 11 | #include <syscon.h> |
1221ce45 | 12 | #include <linux/errno.h> |
1f8f7730 SG |
13 | #include <asm/gpio.h> |
14 | #include <asm/io.h> | |
15f09a1a KY |
15 | #include <asm/arch-rockchip/clock.h> |
16 | #include <asm/arch-rockchip/gpio.h> | |
48647828 | 17 | #include <dm/pinctrl.h> |
48647828 | 18 | #include <dt-bindings/clock/rk3288-cru.h> |
1f8f7730 SG |
19 | |
20 | enum { | |
21 | ROCKCHIP_GPIOS_PER_BANK = 32, | |
22 | }; | |
23 | ||
24 | #define OFFSET_TO_BIT(bit) (1UL << (bit)) | |
25 | ||
26 | struct rockchip_gpio_priv { | |
27 | struct rockchip_gpio_regs *regs; | |
48647828 SG |
28 | struct udevice *pinctrl; |
29 | int bank; | |
1f8f7730 SG |
30 | char name[2]; |
31 | }; | |
32 | ||
33 | static int rockchip_gpio_direction_input(struct udevice *dev, unsigned offset) | |
34 | { | |
35 | struct rockchip_gpio_priv *priv = dev_get_priv(dev); | |
36 | struct rockchip_gpio_regs *regs = priv->regs; | |
37 | ||
38 | clrbits_le32(®s->swport_ddr, OFFSET_TO_BIT(offset)); | |
39 | ||
40 | return 0; | |
41 | } | |
42 | ||
43 | static int rockchip_gpio_direction_output(struct udevice *dev, unsigned offset, | |
44 | int value) | |
45 | { | |
46 | struct rockchip_gpio_priv *priv = dev_get_priv(dev); | |
47 | struct rockchip_gpio_regs *regs = priv->regs; | |
48 | int mask = OFFSET_TO_BIT(offset); | |
49 | ||
50 | clrsetbits_le32(®s->swport_dr, mask, value ? mask : 0); | |
51 | setbits_le32(®s->swport_ddr, mask); | |
52 | ||
53 | return 0; | |
54 | } | |
55 | ||
56 | static int rockchip_gpio_get_value(struct udevice *dev, unsigned offset) | |
57 | { | |
58 | struct rockchip_gpio_priv *priv = dev_get_priv(dev); | |
59 | struct rockchip_gpio_regs *regs = priv->regs; | |
60 | ||
7d0c2c3f | 61 | return readl(®s->ext_port) & OFFSET_TO_BIT(offset) ? 1 : 0; |
1f8f7730 SG |
62 | } |
63 | ||
64 | static int rockchip_gpio_set_value(struct udevice *dev, unsigned offset, | |
65 | int value) | |
66 | { | |
67 | struct rockchip_gpio_priv *priv = dev_get_priv(dev); | |
68 | struct rockchip_gpio_regs *regs = priv->regs; | |
69 | int mask = OFFSET_TO_BIT(offset); | |
70 | ||
71 | clrsetbits_le32(®s->swport_dr, mask, value ? mask : 0); | |
72 | ||
73 | return 0; | |
74 | } | |
75 | ||
76 | static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset) | |
77 | { | |
48647828 SG |
78 | #ifdef CONFIG_SPL_BUILD |
79 | return -ENODATA; | |
80 | #else | |
81 | struct rockchip_gpio_priv *priv = dev_get_priv(dev); | |
82 | struct rockchip_gpio_regs *regs = priv->regs; | |
83 | bool is_output; | |
84 | int ret; | |
85 | ||
86 | ret = pinctrl_get_gpio_mux(priv->pinctrl, priv->bank, offset); | |
87 | if (ret) | |
88 | return ret; | |
48647828 SG |
89 | is_output = readl(®s->swport_ddr) & OFFSET_TO_BIT(offset); |
90 | ||
91 | return is_output ? GPIOF_OUTPUT : GPIOF_INPUT; | |
92 | #endif | |
1f8f7730 SG |
93 | } |
94 | ||
aa48c94c SG |
95 | /* Simple SPL interface to GPIOs */ |
96 | #ifdef CONFIG_SPL_BUILD | |
97 | ||
98 | enum { | |
99 | PULL_NONE_1V8 = 0, | |
100 | PULL_DOWN_1V8 = 1, | |
101 | PULL_UP_1V8 = 3, | |
102 | }; | |
103 | ||
104 | int spl_gpio_set_pull(void *vregs, uint gpio, int pull) | |
105 | { | |
106 | u32 *regs = vregs; | |
107 | uint val; | |
108 | ||
109 | regs += gpio >> GPIO_BANK_SHIFT; | |
110 | gpio &= GPIO_OFFSET_MASK; | |
111 | switch (pull) { | |
112 | case GPIO_PULL_UP: | |
113 | val = PULL_UP_1V8; | |
114 | break; | |
115 | case GPIO_PULL_DOWN: | |
116 | val = PULL_DOWN_1V8; | |
117 | break; | |
118 | case GPIO_PULL_NORMAL: | |
119 | default: | |
120 | val = PULL_NONE_1V8; | |
121 | break; | |
122 | } | |
123 | clrsetbits_le32(regs, 3 << (gpio * 2), val << (gpio * 2)); | |
124 | ||
125 | return 0; | |
126 | } | |
127 | ||
128 | int spl_gpio_output(void *vregs, uint gpio, int value) | |
129 | { | |
130 | struct rockchip_gpio_regs * const regs = vregs; | |
131 | ||
132 | clrsetbits_le32(®s->swport_dr, 1 << gpio, value << gpio); | |
133 | ||
134 | /* Set direction */ | |
135 | clrsetbits_le32(®s->swport_ddr, 1 << gpio, 1 << gpio); | |
136 | ||
137 | return 0; | |
138 | } | |
139 | #endif /* CONFIG_SPL_BUILD */ | |
140 | ||
1f8f7730 SG |
141 | static int rockchip_gpio_probe(struct udevice *dev) |
142 | { | |
143 | struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); | |
144 | struct rockchip_gpio_priv *priv = dev_get_priv(dev); | |
145 | char *end; | |
48647828 | 146 | int ret; |
1f8f7730 | 147 | |
a1d3480b | 148 | priv->regs = dev_read_addr_ptr(dev); |
3f603cbb | 149 | ret = uclass_first_device_err(UCLASS_PINCTRL, &priv->pinctrl); |
48647828 SG |
150 | if (ret) |
151 | return ret; | |
48647828 | 152 | |
1f8f7730 SG |
153 | uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK; |
154 | end = strrchr(dev->name, '@'); | |
48647828 SG |
155 | priv->bank = trailing_strtoln(dev->name, end); |
156 | priv->name[0] = 'A' + priv->bank; | |
1f8f7730 SG |
157 | uc_priv->bank_name = priv->name; |
158 | ||
159 | return 0; | |
160 | } | |
161 | ||
162 | static const struct dm_gpio_ops gpio_rockchip_ops = { | |
163 | .direction_input = rockchip_gpio_direction_input, | |
164 | .direction_output = rockchip_gpio_direction_output, | |
165 | .get_value = rockchip_gpio_get_value, | |
166 | .set_value = rockchip_gpio_set_value, | |
167 | .get_function = rockchip_gpio_get_function, | |
1f8f7730 SG |
168 | }; |
169 | ||
170 | static const struct udevice_id rockchip_gpio_ids[] = { | |
171 | { .compatible = "rockchip,gpio-bank" }, | |
172 | { } | |
173 | }; | |
174 | ||
e3e2470f WL |
175 | U_BOOT_DRIVER(rockchip_gpio_bank) = { |
176 | .name = "rockchip_gpio_bank", | |
1f8f7730 SG |
177 | .id = UCLASS_GPIO, |
178 | .of_match = rockchip_gpio_ids, | |
179 | .ops = &gpio_rockchip_ops, | |
180 | .priv_auto_alloc_size = sizeof(struct rockchip_gpio_priv), | |
181 | .probe = rockchip_gpio_probe, | |
182 | }; |