GNU Linux-libre 5.13.14-gnu1
[releases.git] / drivers / pinctrl / pinconf.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Core driver for the pin config portions of the pin control subsystem
4  *
5  * Copyright (C) 2011 ST-Ericsson SA
6  * Written on behalf of Linaro for ST-Ericsson
7  *
8  * Author: Linus Walleij <linus.walleij@linaro.org>
9  */
10 #define pr_fmt(fmt) "pinconfig core: " fmt
11
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/device.h>
16 #include <linux/slab.h>
17 #include <linux/debugfs.h>
18 #include <linux/seq_file.h>
19 #include <linux/pinctrl/machine.h>
20 #include <linux/pinctrl/pinctrl.h>
21 #include <linux/pinctrl/pinconf.h>
22 #include "core.h"
23 #include "pinconf.h"
24
25 int pinconf_check_ops(struct pinctrl_dev *pctldev)
26 {
27         const struct pinconf_ops *ops = pctldev->desc->confops;
28
29         /* We have to be able to config the pins in SOME way */
30         if (!ops->pin_config_set && !ops->pin_config_group_set) {
31                 dev_err(pctldev->dev,
32                         "pinconf has to be able to set a pins config\n");
33                 return -EINVAL;
34         }
35         return 0;
36 }
37
38 int pinconf_validate_map(const struct pinctrl_map *map, int i)
39 {
40         if (!map->data.configs.group_or_pin) {
41                 pr_err("failed to register map %s (%d): no group/pin given\n",
42                        map->name, i);
43                 return -EINVAL;
44         }
45
46         if (!map->data.configs.num_configs ||
47                         !map->data.configs.configs) {
48                 pr_err("failed to register map %s (%d): no configs given\n",
49                        map->name, i);
50                 return -EINVAL;
51         }
52
53         return 0;
54 }
55
56 int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
57                            unsigned long *config)
58 {
59         const struct pinconf_ops *ops = pctldev->desc->confops;
60
61         if (!ops || !ops->pin_config_get) {
62                 dev_dbg(pctldev->dev,
63                         "cannot get pin configuration, .pin_config_get missing in driver\n");
64                 return -ENOTSUPP;
65         }
66
67         return ops->pin_config_get(pctldev, pin, config);
68 }
69
70 int pin_config_group_get(const char *dev_name, const char *pin_group,
71                          unsigned long *config)
72 {
73         struct pinctrl_dev *pctldev;
74         const struct pinconf_ops *ops;
75         int selector, ret;
76
77         pctldev = get_pinctrl_dev_from_devname(dev_name);
78         if (!pctldev) {
79                 ret = -EINVAL;
80                 return ret;
81         }
82
83         mutex_lock(&pctldev->mutex);
84
85         ops = pctldev->desc->confops;
86
87         if (!ops || !ops->pin_config_group_get) {
88                 dev_dbg(pctldev->dev,
89                         "cannot get configuration for pin group, missing group config get function in driver\n");
90                 ret = -ENOTSUPP;
91                 goto unlock;
92         }
93
94         selector = pinctrl_get_group_selector(pctldev, pin_group);
95         if (selector < 0) {
96                 ret = selector;
97                 goto unlock;
98         }
99
100         ret = ops->pin_config_group_get(pctldev, selector, config);
101
102 unlock:
103         mutex_unlock(&pctldev->mutex);
104         return ret;
105 }
106
107 int pinconf_map_to_setting(const struct pinctrl_map *map,
108                           struct pinctrl_setting *setting)
109 {
110         struct pinctrl_dev *pctldev = setting->pctldev;
111         int pin;
112
113         switch (setting->type) {
114         case PIN_MAP_TYPE_CONFIGS_PIN:
115                 pin = pin_get_from_name(pctldev,
116                                         map->data.configs.group_or_pin);
117                 if (pin < 0) {
118                         dev_err(pctldev->dev, "could not map pin config for \"%s\"",
119                                 map->data.configs.group_or_pin);
120                         return pin;
121                 }
122                 setting->data.configs.group_or_pin = pin;
123                 break;
124         case PIN_MAP_TYPE_CONFIGS_GROUP:
125                 pin = pinctrl_get_group_selector(pctldev,
126                                          map->data.configs.group_or_pin);
127                 if (pin < 0) {
128                         dev_err(pctldev->dev, "could not map group config for \"%s\"",
129                                 map->data.configs.group_or_pin);
130                         return pin;
131                 }
132                 setting->data.configs.group_or_pin = pin;
133                 break;
134         default:
135                 return -EINVAL;
136         }
137
138         setting->data.configs.num_configs = map->data.configs.num_configs;
139         setting->data.configs.configs = map->data.configs.configs;
140
141         return 0;
142 }
143
144 void pinconf_free_setting(const struct pinctrl_setting *setting)
145 {
146 }
147
148 int pinconf_apply_setting(const struct pinctrl_setting *setting)
149 {
150         struct pinctrl_dev *pctldev = setting->pctldev;
151         const struct pinconf_ops *ops = pctldev->desc->confops;
152         int ret;
153
154         if (!ops) {
155                 dev_err(pctldev->dev, "missing confops\n");
156                 return -EINVAL;
157         }
158
159         switch (setting->type) {
160         case PIN_MAP_TYPE_CONFIGS_PIN:
161                 if (!ops->pin_config_set) {
162                         dev_err(pctldev->dev, "missing pin_config_set op\n");
163                         return -EINVAL;
164                 }
165                 ret = ops->pin_config_set(pctldev,
166                                 setting->data.configs.group_or_pin,
167                                 setting->data.configs.configs,
168                                 setting->data.configs.num_configs);
169                 if (ret < 0) {
170                         dev_err(pctldev->dev,
171                                 "pin_config_set op failed for pin %d\n",
172                                 setting->data.configs.group_or_pin);
173                         return ret;
174                 }
175                 break;
176         case PIN_MAP_TYPE_CONFIGS_GROUP:
177                 if (!ops->pin_config_group_set) {
178                         dev_err(pctldev->dev,
179                                 "missing pin_config_group_set op\n");
180                         return -EINVAL;
181                 }
182                 ret = ops->pin_config_group_set(pctldev,
183                                 setting->data.configs.group_or_pin,
184                                 setting->data.configs.configs,
185                                 setting->data.configs.num_configs);
186                 if (ret < 0) {
187                         dev_err(pctldev->dev,
188                                 "pin_config_group_set op failed for group %d\n",
189                                 setting->data.configs.group_or_pin);
190                         return ret;
191                 }
192                 break;
193         default:
194                 return -EINVAL;
195         }
196
197         return 0;
198 }
199
200 int pinconf_set_config(struct pinctrl_dev *pctldev, unsigned pin,
201                        unsigned long *configs, size_t nconfigs)
202 {
203         const struct pinconf_ops *ops;
204
205         ops = pctldev->desc->confops;
206         if (!ops || !ops->pin_config_set)
207                 return -ENOTSUPP;
208
209         return ops->pin_config_set(pctldev, pin, configs, nconfigs);
210 }
211
212 #ifdef CONFIG_DEBUG_FS
213
214 static void pinconf_show_config(struct seq_file *s, struct pinctrl_dev *pctldev,
215                       unsigned long *configs, unsigned num_configs)
216 {
217         const struct pinconf_ops *confops;
218         int i;
219
220         if (pctldev)
221                 confops = pctldev->desc->confops;
222         else
223                 confops = NULL;
224
225         for (i = 0; i < num_configs; i++) {
226                 seq_puts(s, "config ");
227                 if (confops && confops->pin_config_config_dbg_show)
228                         confops->pin_config_config_dbg_show(pctldev, s,
229                                                             configs[i]);
230                 else
231                         seq_printf(s, "%08lx", configs[i]);
232                 seq_putc(s, '\n');
233         }
234 }
235
236 void pinconf_show_map(struct seq_file *s, const struct pinctrl_map *map)
237 {
238         struct pinctrl_dev *pctldev;
239
240         pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
241
242         switch (map->type) {
243         case PIN_MAP_TYPE_CONFIGS_PIN:
244                 seq_puts(s, "pin ");
245                 break;
246         case PIN_MAP_TYPE_CONFIGS_GROUP:
247                 seq_puts(s, "group ");
248                 break;
249         default:
250                 break;
251         }
252
253         seq_printf(s, "%s\n", map->data.configs.group_or_pin);
254
255         pinconf_show_config(s, pctldev, map->data.configs.configs,
256                             map->data.configs.num_configs);
257 }
258
259 void pinconf_show_setting(struct seq_file *s,
260                           const struct pinctrl_setting *setting)
261 {
262         struct pinctrl_dev *pctldev = setting->pctldev;
263         const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
264         struct pin_desc *desc;
265
266         switch (setting->type) {
267         case PIN_MAP_TYPE_CONFIGS_PIN:
268                 desc = pin_desc_get(setting->pctldev,
269                                     setting->data.configs.group_or_pin);
270                 seq_printf(s, "pin %s (%d)", desc->name,
271                            setting->data.configs.group_or_pin);
272                 break;
273         case PIN_MAP_TYPE_CONFIGS_GROUP:
274                 seq_printf(s, "group %s (%d)",
275                            pctlops->get_group_name(pctldev,
276                                         setting->data.configs.group_or_pin),
277                            setting->data.configs.group_or_pin);
278                 break;
279         default:
280                 break;
281         }
282
283         /*
284          * FIXME: We should really get the pin controller to dump the config
285          * values, so they can be decoded to something meaningful.
286          */
287         pinconf_show_config(s, pctldev, setting->data.configs.configs,
288                             setting->data.configs.num_configs);
289 }
290
291 static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
292                              struct seq_file *s, int pin)
293 {
294         const struct pinconf_ops *ops = pctldev->desc->confops;
295
296         /* no-op when not using generic pin config */
297         pinconf_generic_dump_pins(pctldev, s, NULL, pin);
298         if (ops && ops->pin_config_dbg_show)
299                 ops->pin_config_dbg_show(pctldev, s, pin);
300 }
301
302 static int pinconf_pins_show(struct seq_file *s, void *what)
303 {
304         struct pinctrl_dev *pctldev = s->private;
305         unsigned i, pin;
306
307         seq_puts(s, "Pin config settings per pin\n");
308         seq_puts(s, "Format: pin (name): configs\n");
309
310         mutex_lock(&pctldev->mutex);
311
312         /* The pin number can be retrived from the pin controller descriptor */
313         for (i = 0; i < pctldev->desc->npins; i++) {
314                 struct pin_desc *desc;
315
316                 pin = pctldev->desc->pins[i].number;
317                 desc = pin_desc_get(pctldev, pin);
318                 /* Skip if we cannot search the pin */
319                 if (!desc)
320                         continue;
321
322                 seq_printf(s, "pin %d (%s): ", pin, desc->name);
323
324                 pinconf_dump_pin(pctldev, s, pin);
325                 seq_putc(s, '\n');
326         }
327
328         mutex_unlock(&pctldev->mutex);
329
330         return 0;
331 }
332
333 static void pinconf_dump_group(struct pinctrl_dev *pctldev,
334                                struct seq_file *s, unsigned selector,
335                                const char *gname)
336 {
337         const struct pinconf_ops *ops = pctldev->desc->confops;
338
339         /* no-op when not using generic pin config */
340         pinconf_generic_dump_pins(pctldev, s, gname, 0);
341         if (ops && ops->pin_config_group_dbg_show)
342                 ops->pin_config_group_dbg_show(pctldev, s, selector);
343 }
344
345 static int pinconf_groups_show(struct seq_file *s, void *what)
346 {
347         struct pinctrl_dev *pctldev = s->private;
348         const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
349         unsigned ngroups = pctlops->get_groups_count(pctldev);
350         unsigned selector = 0;
351
352         seq_puts(s, "Pin config settings per pin group\n");
353         seq_puts(s, "Format: group (name): configs\n");
354
355         while (selector < ngroups) {
356                 const char *gname = pctlops->get_group_name(pctldev, selector);
357
358                 seq_printf(s, "%u (%s): ", selector, gname);
359                 pinconf_dump_group(pctldev, s, selector, gname);
360                 seq_putc(s, '\n');
361                 selector++;
362         }
363
364         return 0;
365 }
366
367 DEFINE_SHOW_ATTRIBUTE(pinconf_pins);
368 DEFINE_SHOW_ATTRIBUTE(pinconf_groups);
369
370 void pinconf_init_device_debugfs(struct dentry *devroot,
371                          struct pinctrl_dev *pctldev)
372 {
373         debugfs_create_file("pinconf-pins", 0444,
374                             devroot, pctldev, &pinconf_pins_fops);
375         debugfs_create_file("pinconf-groups", 0444,
376                             devroot, pctldev, &pinconf_groups_fops);
377 }
378
379 #endif