common: Drop log.h from common header
[platform/kernel/u-boot.git] / drivers / pinctrl / meson / pinctrl-meson.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2016 - Beniamino Galvani <b.galvani@gmail.com>
4  */
5
6 #include <common.h>
7 #include <dm.h>
8 #include <log.h>
9 #include <malloc.h>
10 #include <dm/device-internal.h>
11 #include <dm/device_compat.h>
12 #include <dm/lists.h>
13 #include <dm/pinctrl.h>
14 #include <fdt_support.h>
15 #include <linux/err.h>
16 #include <linux/io.h>
17 #include <linux/libfdt.h>
18 #include <linux/sizes.h>
19 #include <asm/gpio.h>
20
21 #include "pinctrl-meson.h"
22
23 DECLARE_GLOBAL_DATA_PTR;
24
25 static const char *meson_pinctrl_dummy_name = "_dummy";
26
27 static char pin_name[PINNAME_SIZE];
28
29 int meson_pinctrl_get_groups_count(struct udevice *dev)
30 {
31         struct meson_pinctrl *priv = dev_get_priv(dev);
32
33         return priv->data->num_groups;
34 }
35
36 const char *meson_pinctrl_get_group_name(struct udevice *dev,
37                                          unsigned int selector)
38 {
39         struct meson_pinctrl *priv = dev_get_priv(dev);
40
41         if (!priv->data->groups[selector].name)
42                 return meson_pinctrl_dummy_name;
43
44         return priv->data->groups[selector].name;
45 }
46
47 int meson_pinctrl_get_pins_count(struct udevice *dev)
48 {
49         struct meson_pinctrl *priv = dev_get_priv(dev);
50
51         return priv->data->num_pins;
52 }
53
54 const char *meson_pinctrl_get_pin_name(struct udevice *dev,
55                                        unsigned int selector)
56 {
57         struct meson_pinctrl *priv = dev_get_priv(dev);
58
59         if (selector > priv->data->num_pins ||
60             selector > priv->data->funcs[0].num_groups)
61                 snprintf(pin_name, PINNAME_SIZE, "Error");
62         else
63                 snprintf(pin_name, PINNAME_SIZE, "%s",
64                          priv->data->funcs[0].groups[selector]);
65
66         return pin_name;
67 }
68
69 int meson_pinmux_get_functions_count(struct udevice *dev)
70 {
71         struct meson_pinctrl *priv = dev_get_priv(dev);
72
73         return priv->data->num_funcs;
74 }
75
76 const char *meson_pinmux_get_function_name(struct udevice *dev,
77                                            unsigned int selector)
78 {
79         struct meson_pinctrl *priv = dev_get_priv(dev);
80
81         return priv->data->funcs[selector].name;
82 }
83
84 static int meson_gpio_calc_reg_and_bit(struct udevice *dev, unsigned int offset,
85                                        enum meson_reg_type reg_type,
86                                        unsigned int *reg, unsigned int *bit)
87 {
88         struct meson_pinctrl *priv = dev_get_priv(dev);
89         struct meson_bank *bank = NULL;
90         struct meson_reg_desc *desc;
91         unsigned int pin;
92         int i;
93
94         pin = priv->data->pin_base + offset;
95
96         for (i = 0; i < priv->data->num_banks; i++) {
97                 if (pin >= priv->data->banks[i].first &&
98                     pin <= priv->data->banks[i].last) {
99                         bank = &priv->data->banks[i];
100                         break;
101                 }
102         }
103
104         if (!bank)
105                 return -EINVAL;
106
107         desc = &bank->regs[reg_type];
108         *reg = desc->reg * 4;
109         *bit = desc->bit + pin - bank->first;
110
111         return 0;
112 }
113
114 int meson_gpio_get(struct udevice *dev, unsigned int offset)
115 {
116         struct meson_pinctrl *priv = dev_get_priv(dev->parent);
117         unsigned int reg, bit;
118         int ret;
119
120         ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_IN, &reg,
121                                           &bit);
122         if (ret)
123                 return ret;
124
125         return !!(readl(priv->reg_gpio + reg) & BIT(bit));
126 }
127
128 int meson_gpio_set(struct udevice *dev, unsigned int offset, int value)
129 {
130         struct meson_pinctrl *priv = dev_get_priv(dev->parent);
131         unsigned int reg, bit;
132         int ret;
133
134         ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_OUT, &reg,
135                                           &bit);
136         if (ret)
137                 return ret;
138
139         clrsetbits_le32(priv->reg_gpio + reg, BIT(bit), value ? BIT(bit) : 0);
140
141         return 0;
142 }
143
144 int meson_gpio_get_direction(struct udevice *dev, unsigned int offset)
145 {
146         struct meson_pinctrl *priv = dev_get_priv(dev->parent);
147         unsigned int reg, bit, val;
148         int ret;
149
150         ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_DIR, &reg,
151                                           &bit);
152         if (ret)
153                 return ret;
154
155         val = readl(priv->reg_gpio + reg);
156
157         return (val & BIT(bit)) ? GPIOF_INPUT : GPIOF_OUTPUT;
158 }
159
160 int meson_gpio_direction_input(struct udevice *dev, unsigned int offset)
161 {
162         struct meson_pinctrl *priv = dev_get_priv(dev->parent);
163         unsigned int reg, bit;
164         int ret;
165
166         ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_DIR, &reg,
167                                           &bit);
168         if (ret)
169                 return ret;
170
171         setbits_le32(priv->reg_gpio + reg, BIT(bit));
172
173         return 0;
174 }
175
176 int meson_gpio_direction_output(struct udevice *dev,
177                                 unsigned int offset, int value)
178 {
179         struct meson_pinctrl *priv = dev_get_priv(dev->parent);
180         unsigned int reg, bit;
181         int ret;
182
183         ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_DIR, &reg,
184                                           &bit);
185         if (ret)
186                 return ret;
187
188         clrbits_le32(priv->reg_gpio + reg, BIT(bit));
189
190         ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_OUT, &reg,
191                                           &bit);
192         if (ret)
193                 return ret;
194
195         clrsetbits_le32(priv->reg_gpio + reg, BIT(bit), value ? BIT(bit) : 0);
196
197         return 0;
198 }
199
200 static int meson_pinconf_bias_set(struct udevice *dev, unsigned int pin,
201                                   unsigned int param)
202 {
203         struct meson_pinctrl *priv = dev_get_priv(dev);
204         unsigned int offset = pin - priv->data->pin_base;
205         unsigned int reg, bit;
206         int ret;
207
208         ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_PULLEN, &reg, &bit);
209         if (ret)
210                 return ret;
211
212         if (param == PIN_CONFIG_BIAS_DISABLE) {
213                 clrsetbits_le32(priv->reg_pullen + reg, BIT(bit), 0);
214                 return 0;
215         }
216
217         /* othewise, enable the bias and select level */
218         clrsetbits_le32(priv->reg_pullen + reg, BIT(bit), 1);
219         ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_PULL, &reg, &bit);
220         if (ret)
221                 return ret;
222
223         clrsetbits_le32(priv->reg_pull + reg, BIT(bit),
224                         param == PIN_CONFIG_BIAS_PULL_UP);
225
226         return 0;
227 }
228
229 static int meson_pinconf_drive_strength_set(struct udevice *dev,
230                                             unsigned int pin,
231                                             unsigned int drive_strength_ua)
232 {
233         struct meson_pinctrl *priv = dev_get_priv(dev);
234         unsigned int offset = pin - priv->data->pin_base;
235         unsigned int reg, bit;
236         unsigned int ds_val;
237         int ret;
238
239         if (!priv->reg_ds) {
240                 dev_err(dev, "drive-strength-microamp not supported\n");
241                 return -ENOTSUPP;
242         }
243
244         ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_DS, &reg, &bit);
245         if (ret)
246                 return ret;
247
248         bit = bit << 1;
249
250         if (drive_strength_ua <= 500) {
251                 ds_val = MESON_PINCONF_DRV_500UA;
252         } else if (drive_strength_ua <= 2500) {
253                 ds_val = MESON_PINCONF_DRV_2500UA;
254         } else if (drive_strength_ua <= 3000) {
255                 ds_val = MESON_PINCONF_DRV_3000UA;
256         } else if (drive_strength_ua <= 4000) {
257                 ds_val = MESON_PINCONF_DRV_4000UA;
258         } else {
259                 dev_warn(dev,
260                          "pin %u: invalid drive-strength-microamp : %d , default to 4mA\n",
261                          pin, drive_strength_ua);
262                 ds_val = MESON_PINCONF_DRV_4000UA;
263         }
264
265         clrsetbits_le32(priv->reg_ds + reg, 0x3 << bit, ds_val << bit);
266
267         return 0;
268 }
269
270 int meson_pinconf_set(struct udevice *dev, unsigned int pin,
271                       unsigned int param, unsigned int arg)
272 {
273         int ret;
274
275         switch (param) {
276         case PIN_CONFIG_BIAS_DISABLE:
277         case PIN_CONFIG_BIAS_PULL_UP:
278         case PIN_CONFIG_BIAS_PULL_DOWN:
279                 ret = meson_pinconf_bias_set(dev, pin, param);
280                 break;
281         case PIN_CONFIG_DRIVE_STRENGTH_UA:
282                 ret = meson_pinconf_drive_strength_set(dev, pin, arg);
283                 break;
284         default:
285                 dev_err(dev, "unsupported configuration parameter %u\n", param);
286                 return -EINVAL;
287         }
288
289         return ret;
290 }
291
292 int meson_pinconf_group_set(struct udevice *dev,
293                             unsigned int group_selector,
294                             unsigned int param, unsigned int arg)
295 {
296         struct meson_pinctrl *priv = dev_get_priv(dev);
297         struct meson_pmx_group *grp = &priv->data->groups[group_selector];
298         int i, ret;
299
300         for (i = 0; i < grp->num_pins; i++) {
301                 ret = meson_pinconf_set(dev, grp->pins[i], param, arg);
302                 if (ret)
303                         return ret;
304         }
305
306         return 0;
307 }
308
309 int meson_gpio_probe(struct udevice *dev)
310 {
311         struct meson_pinctrl *priv = dev_get_priv(dev->parent);
312         struct gpio_dev_priv *uc_priv;
313
314         uc_priv = dev_get_uclass_priv(dev);
315         uc_priv->bank_name = priv->data->name;
316         uc_priv->gpio_count = priv->data->num_pins;
317
318         return 0;
319 }
320
321 static fdt_addr_t parse_address(int offset, const char *name, int na, int ns)
322 {
323         int index, len = 0;
324         const fdt32_t *reg;
325
326         index = fdt_stringlist_search(gd->fdt_blob, offset, "reg-names", name);
327         if (index < 0)
328                 return FDT_ADDR_T_NONE;
329
330         reg = fdt_getprop(gd->fdt_blob, offset, "reg", &len);
331         if (!reg || (len <= (index * sizeof(fdt32_t) * (na + ns))))
332                 return FDT_ADDR_T_NONE;
333
334         reg += index * (na + ns);
335
336         return fdt_translate_address((void *)gd->fdt_blob, offset, reg);
337 }
338
339 int meson_pinctrl_probe(struct udevice *dev)
340 {
341         struct meson_pinctrl *priv = dev_get_priv(dev);
342         struct uclass_driver *drv;
343         struct udevice *gpio_dev;
344         fdt_addr_t addr;
345         int node, gpio = -1, len;
346         int na, ns;
347         char *name;
348
349         na = fdt_address_cells(gd->fdt_blob, dev_of_offset(dev->parent));
350         if (na < 1) {
351                 debug("bad #address-cells\n");
352                 return -EINVAL;
353         }
354
355         ns = fdt_size_cells(gd->fdt_blob, dev_of_offset(dev->parent));
356         if (ns < 1) {
357                 debug("bad #size-cells\n");
358                 return -EINVAL;
359         }
360
361         fdt_for_each_subnode(node, gd->fdt_blob, dev_of_offset(dev)) {
362                 if (fdt_getprop(gd->fdt_blob, node, "gpio-controller", &len)) {
363                         gpio = node;
364                         break;
365                 }
366         }
367
368         if (!gpio) {
369                 debug("gpio node not found\n");
370                 return -EINVAL;
371         }
372
373         addr = parse_address(gpio, "mux", na, ns);
374         if (addr == FDT_ADDR_T_NONE) {
375                 debug("mux address not found\n");
376                 return -EINVAL;
377         }
378         priv->reg_mux = (void __iomem *)addr;
379
380         addr = parse_address(gpio, "gpio", na, ns);
381         if (addr == FDT_ADDR_T_NONE) {
382                 debug("gpio address not found\n");
383                 return -EINVAL;
384         }
385         priv->reg_gpio = (void __iomem *)addr;
386
387         addr = parse_address(gpio, "pull", na, ns);
388         /* Use gpio region if pull one is not present */
389         if (addr == FDT_ADDR_T_NONE)
390                 priv->reg_pull = priv->reg_gpio;
391         else
392                 priv->reg_pull = (void __iomem *)addr;
393
394         addr = parse_address(gpio, "pull-enable", na, ns);
395         /* Use pull region if pull-enable one is not present */
396         if (addr == FDT_ADDR_T_NONE)
397                 priv->reg_pullen = priv->reg_pull;
398         else
399                 priv->reg_pullen = (void __iomem *)addr;
400
401         addr = parse_address(gpio, "ds", na, ns);
402         /* Drive strength region is optional */
403         if (addr == FDT_ADDR_T_NONE)
404                 priv->reg_ds = NULL;
405         else
406                 priv->reg_ds = (void __iomem *)addr;
407
408         priv->data = (struct meson_pinctrl_data *)dev_get_driver_data(dev);
409
410         /* Lookup GPIO driver */
411         drv = lists_uclass_lookup(UCLASS_GPIO);
412         if (!drv) {
413                 puts("Cannot find GPIO driver\n");
414                 return -ENOENT;
415         }
416
417         name = calloc(1, 32);
418         sprintf(name, "meson-gpio");
419
420         /* Create child device UCLASS_GPIO and bind it */
421         device_bind(dev, priv->data->gpio_driver, name, NULL, gpio, &gpio_dev);
422         dev_set_of_offset(gpio_dev, gpio);
423
424         return 0;
425 }