8da2d6db228c07dc17fd0f83b17f50238b2e7ef2
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / pinctrl / pinconf.c
1 /*
2  * Core driver for the pin config portions of the pin control subsystem
3  *
4  * Copyright (C) 2011 ST-Ericsson SA
5  * Written on behalf of Linaro for ST-Ericsson
6  *
7  * Author: Linus Walleij <linus.walleij@linaro.org>
8  *
9  * License terms: GNU General Public License (GPL) version 2
10  */
11 #define pr_fmt(fmt) "pinconfig core: " fmt
12
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/device.h>
17 #include <linux/slab.h>
18 #include <linux/debugfs.h>
19 #include <linux/seq_file.h>
20 #include <linux/uaccess.h>
21 #include <linux/pinctrl/machine.h>
22 #include <linux/pinctrl/pinctrl.h>
23 #include <linux/pinctrl/pinconf.h>
24 #include "core.h"
25 #include "pinconf.h"
26
27 int pinconf_check_ops(struct pinctrl_dev *pctldev)
28 {
29         const struct pinconf_ops *ops = pctldev->desc->confops;
30
31         /* We must be able to read out pin status */
32         if (!ops->pin_config_get && !ops->pin_config_group_get) {
33                 dev_err(pctldev->dev,
34                         "pinconf must be able to read out pin status\n");
35                 return -EINVAL;
36         }
37         /* We have to be able to config the pins in SOME way */
38         if (!ops->pin_config_set && !ops->pin_config_group_set) {
39                 dev_err(pctldev->dev,
40                         "pinconf has to be able to set a pins config\n");
41                 return -EINVAL;
42         }
43         return 0;
44 }
45
46 int pinconf_validate_map(struct pinctrl_map const *map, int i)
47 {
48         if (!map->data.configs.group_or_pin) {
49                 pr_err("failed to register map %s (%d): no group/pin given\n",
50                        map->name, i);
51                 return -EINVAL;
52         }
53
54         if (!map->data.configs.num_configs ||
55                         !map->data.configs.configs) {
56                 pr_err("failed to register map %s (%d): no configs given\n",
57                        map->name, i);
58                 return -EINVAL;
59         }
60
61         return 0;
62 }
63
64 int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
65                            unsigned long *config)
66 {
67         const struct pinconf_ops *ops = pctldev->desc->confops;
68
69         if (!ops || !ops->pin_config_get) {
70                 dev_err(pctldev->dev, "cannot get pin configuration, missing "
71                         "pin_config_get() function in driver\n");
72                 return -EINVAL;
73         }
74
75         return ops->pin_config_get(pctldev, pin, config);
76 }
77
78 int pin_config_group_get(const char *dev_name, const char *pin_group,
79                          unsigned long *config)
80 {
81         struct pinctrl_dev *pctldev;
82         const struct pinconf_ops *ops;
83         int selector, ret;
84
85         pctldev = get_pinctrl_dev_from_devname(dev_name);
86         if (!pctldev) {
87                 ret = -EINVAL;
88                 return ret;
89         }
90
91         mutex_lock(&pctldev->mutex);
92
93         ops = pctldev->desc->confops;
94
95         if (!ops || !ops->pin_config_group_get) {
96                 dev_err(pctldev->dev, "cannot get configuration for pin "
97                         "group, missing group config get function in "
98                         "driver\n");
99                 ret = -EINVAL;
100                 goto unlock;
101         }
102
103         selector = pinctrl_get_group_selector(pctldev, pin_group);
104         if (selector < 0) {
105                 ret = selector;
106                 goto unlock;
107         }
108
109         ret = ops->pin_config_group_get(pctldev, selector, config);
110
111 unlock:
112         mutex_unlock(&pctldev->mutex);
113         return ret;
114 }
115
116 int pinconf_map_to_setting(struct pinctrl_map const *map,
117                           struct pinctrl_setting *setting)
118 {
119         struct pinctrl_dev *pctldev = setting->pctldev;
120         int pin;
121
122         switch (setting->type) {
123         case PIN_MAP_TYPE_CONFIGS_PIN:
124                 pin = pin_get_from_name(pctldev,
125                                         map->data.configs.group_or_pin);
126                 if (pin < 0) {
127                         dev_err(pctldev->dev, "could not map pin config for \"%s\"",
128                                 map->data.configs.group_or_pin);
129                         return pin;
130                 }
131                 setting->data.configs.group_or_pin = pin;
132                 break;
133         case PIN_MAP_TYPE_CONFIGS_GROUP:
134                 pin = pinctrl_get_group_selector(pctldev,
135                                          map->data.configs.group_or_pin);
136                 if (pin < 0) {
137                         dev_err(pctldev->dev, "could not map group config for \"%s\"",
138                                 map->data.configs.group_or_pin);
139                         return pin;
140                 }
141                 setting->data.configs.group_or_pin = pin;
142                 break;
143         default:
144                 return -EINVAL;
145         }
146
147         setting->data.configs.num_configs = map->data.configs.num_configs;
148         setting->data.configs.configs = map->data.configs.configs;
149
150         return 0;
151 }
152
153 void pinconf_free_setting(struct pinctrl_setting const *setting)
154 {
155 }
156
157 int pinconf_apply_setting(struct pinctrl_setting const *setting)
158 {
159         struct pinctrl_dev *pctldev = setting->pctldev;
160         const struct pinconf_ops *ops = pctldev->desc->confops;
161         int i, ret;
162
163         if (!ops) {
164                 dev_err(pctldev->dev, "missing confops\n");
165                 return -EINVAL;
166         }
167
168         switch (setting->type) {
169         case PIN_MAP_TYPE_CONFIGS_PIN:
170                 if (!ops->pin_config_set) {
171                         dev_err(pctldev->dev, "missing pin_config_set op\n");
172                         return -EINVAL;
173                 }
174                 for (i = 0; i < setting->data.configs.num_configs; i++) {
175                         ret = ops->pin_config_set(pctldev,
176                                         setting->data.configs.group_or_pin,
177                                         setting->data.configs.configs[i]);
178                         if (ret < 0) {
179                                 dev_err(pctldev->dev,
180                                         "pin_config_set op failed for pin %d config %08lx\n",
181                                         setting->data.configs.group_or_pin,
182                                         setting->data.configs.configs[i]);
183                                 return ret;
184                         }
185                 }
186                 break;
187         case PIN_MAP_TYPE_CONFIGS_GROUP:
188                 if (!ops->pin_config_group_set) {
189                         dev_err(pctldev->dev,
190                                 "missing pin_config_group_set op\n");
191                         return -EINVAL;
192                 }
193                 for (i = 0; i < setting->data.configs.num_configs; i++) {
194                         ret = ops->pin_config_group_set(pctldev,
195                                         setting->data.configs.group_or_pin,
196                                         setting->data.configs.configs[i]);
197                         if (ret < 0) {
198                                 dev_err(pctldev->dev,
199                                         "pin_config_group_set op failed for group %d config %08lx\n",
200                                         setting->data.configs.group_or_pin,
201                                         setting->data.configs.configs[i]);
202                                 return ret;
203                         }
204                 }
205                 break;
206         default:
207                 return -EINVAL;
208         }
209
210         return 0;
211 }
212
213 #ifdef CONFIG_DEBUG_FS
214
215 void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map)
216 {
217         struct pinctrl_dev *pctldev;
218         const struct pinconf_ops *confops;
219         int i;
220
221         pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
222         if (pctldev)
223                 confops = pctldev->desc->confops;
224         else
225                 confops = NULL;
226
227         switch (map->type) {
228         case PIN_MAP_TYPE_CONFIGS_PIN:
229                 seq_printf(s, "pin ");
230                 break;
231         case PIN_MAP_TYPE_CONFIGS_GROUP:
232                 seq_printf(s, "group ");
233                 break;
234         default:
235                 break;
236         }
237
238         seq_printf(s, "%s\n", map->data.configs.group_or_pin);
239
240         for (i = 0; i < map->data.configs.num_configs; i++) {
241                 seq_printf(s, "config ");
242                 if (confops && confops->pin_config_config_dbg_show)
243                         confops->pin_config_config_dbg_show(pctldev, s,
244                                                 map->data.configs.configs[i]);
245                 else
246                         seq_printf(s, "%08lx", map->data.configs.configs[i]);
247                 seq_printf(s, "\n");
248         }
249 }
250
251 void pinconf_show_setting(struct seq_file *s,
252                           struct pinctrl_setting const *setting)
253 {
254         struct pinctrl_dev *pctldev = setting->pctldev;
255         const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
256         const struct pinconf_ops *confops = pctldev->desc->confops;
257         struct pin_desc *desc;
258         int i;
259
260         switch (setting->type) {
261         case PIN_MAP_TYPE_CONFIGS_PIN:
262                 desc = pin_desc_get(setting->pctldev,
263                                     setting->data.configs.group_or_pin);
264                 seq_printf(s, "pin %s (%d)",
265                            desc->name ? desc->name : "unnamed",
266                            setting->data.configs.group_or_pin);
267                 break;
268         case PIN_MAP_TYPE_CONFIGS_GROUP:
269                 seq_printf(s, "group %s (%d)",
270                            pctlops->get_group_name(pctldev,
271                                         setting->data.configs.group_or_pin),
272                            setting->data.configs.group_or_pin);
273                 break;
274         default:
275                 break;
276         }
277
278         /*
279          * FIXME: We should really get the pin controler to dump the config
280          * values, so they can be decoded to something meaningful.
281          */
282         for (i = 0; i < setting->data.configs.num_configs; i++) {
283                 seq_printf(s, " ");
284                 if (confops && confops->pin_config_config_dbg_show)
285                         confops->pin_config_config_dbg_show(pctldev, s,
286                                 setting->data.configs.configs[i]);
287                 else
288                         seq_printf(s, "%08lx",
289                                    setting->data.configs.configs[i]);
290         }
291
292         seq_printf(s, "\n");
293 }
294
295 static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
296                              struct seq_file *s, int pin)
297 {
298         const struct pinconf_ops *ops = pctldev->desc->confops;
299
300         /* no-op when not using generic pin config */
301         pinconf_generic_dump_pin(pctldev, s, pin);
302         if (ops && ops->pin_config_dbg_show)
303                 ops->pin_config_dbg_show(pctldev, s, pin);
304 }
305
306 static int pinconf_pins_show(struct seq_file *s, void *what)
307 {
308         struct pinctrl_dev *pctldev = s->private;
309         const struct pinconf_ops *ops = pctldev->desc->confops;
310         unsigned i, pin;
311
312         if (!ops || !ops->pin_config_get)
313                 return 0;
314
315         seq_puts(s, "Pin config settings per pin\n");
316         seq_puts(s, "Format: pin (name): configs\n");
317
318         mutex_lock(&pctldev->mutex);
319
320         /* The pin number can be retrived from the pin controller descriptor */
321         for (i = 0; i < pctldev->desc->npins; i++) {
322                 struct pin_desc *desc;
323
324                 pin = pctldev->desc->pins[i].number;
325                 desc = pin_desc_get(pctldev, pin);
326                 /* Skip if we cannot search the pin */
327                 if (desc == NULL)
328                         continue;
329
330                 seq_printf(s, "pin %d (%s):", pin,
331                            desc->name ? desc->name : "unnamed");
332
333                 pinconf_dump_pin(pctldev, s, pin);
334
335                 seq_printf(s, "\n");
336         }
337
338         mutex_unlock(&pctldev->mutex);
339
340         return 0;
341 }
342
343 static void pinconf_dump_group(struct pinctrl_dev *pctldev,
344                                struct seq_file *s, unsigned selector,
345                                const char *gname)
346 {
347         const struct pinconf_ops *ops = pctldev->desc->confops;
348
349         /* no-op when not using generic pin config */
350         pinconf_generic_dump_group(pctldev, s, gname);
351         if (ops && ops->pin_config_group_dbg_show)
352                 ops->pin_config_group_dbg_show(pctldev, s, selector);
353 }
354
355 static int pinconf_groups_show(struct seq_file *s, void *what)
356 {
357         struct pinctrl_dev *pctldev = s->private;
358         const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
359         const struct pinconf_ops *ops = pctldev->desc->confops;
360         unsigned ngroups = pctlops->get_groups_count(pctldev);
361         unsigned selector = 0;
362
363         if (!ops || !ops->pin_config_group_get)
364                 return 0;
365
366         seq_puts(s, "Pin config settings per pin group\n");
367         seq_puts(s, "Format: group (name): configs\n");
368
369         while (selector < ngroups) {
370                 const char *gname = pctlops->get_group_name(pctldev, selector);
371
372                 seq_printf(s, "%u (%s):", selector, gname);
373                 pinconf_dump_group(pctldev, s, selector, gname);
374                 seq_printf(s, "\n");
375
376                 selector++;
377         }
378
379         return 0;
380 }
381
382 static int pinconf_pins_open(struct inode *inode, struct file *file)
383 {
384         return single_open(file, pinconf_pins_show, inode->i_private);
385 }
386
387 static int pinconf_groups_open(struct inode *inode, struct file *file)
388 {
389         return single_open(file, pinconf_groups_show, inode->i_private);
390 }
391
392 static const struct file_operations pinconf_pins_ops = {
393         .open           = pinconf_pins_open,
394         .read           = seq_read,
395         .llseek         = seq_lseek,
396         .release        = single_release,
397 };
398
399 static const struct file_operations pinconf_groups_ops = {
400         .open           = pinconf_groups_open,
401         .read           = seq_read,
402         .llseek         = seq_lseek,
403         .release        = single_release,
404 };
405
406 #define MAX_NAME_LEN 15
407
408 struct dbg_cfg {
409         enum pinctrl_map_type map_type;
410         char dev_name[MAX_NAME_LEN+1];
411         char state_name[MAX_NAME_LEN+1];
412         char pin_name[MAX_NAME_LEN+1];
413 };
414
415 /*
416  * Goal is to keep this structure as global in order to simply read the
417  * pinconf-config file after a write to check config is as expected
418  */
419 static struct dbg_cfg pinconf_dbg_conf;
420
421 /**
422  * pinconf_dbg_config_print() - display the pinctrl config from the pinctrl
423  * map, of the dev/pin/state that was last written to pinconf-config file.
424  * @s: string filled in  with config description
425  * @d: not used
426  */
427 static int pinconf_dbg_config_print(struct seq_file *s, void *d)
428 {
429         struct pinctrl_maps *maps_node;
430         const struct pinctrl_map *map;
431         const struct pinctrl_map *found = NULL;
432         struct pinctrl_dev *pctldev;
433         const struct pinconf_ops *confops = NULL;
434         struct dbg_cfg *dbg = &pinconf_dbg_conf;
435         int i, j;
436         unsigned long config;
437
438         mutex_lock(&pinctrl_maps_mutex);
439
440         /* Parse the pinctrl map and look for the elected pin/state */
441         for_each_maps(maps_node, i, map) {
442                 if (map->type != dbg->map_type)
443                         continue;
444                 if (strcmp(map->dev_name, dbg->dev_name))
445                         continue;
446                 if (strcmp(map->name, dbg->state_name))
447                         continue;
448
449                 for (j = 0; j < map->data.configs.num_configs; j++) {
450                         if (!strcmp(map->data.configs.group_or_pin,
451                                         dbg->pin_name)) {
452                                 /* We found the right pin / state */
453                                 found = map;
454                                 break;
455                         }
456                 }
457         }
458
459         if (!found) {
460                 seq_printf(s, "No config found for dev/state/pin, expected:\n");
461                 seq_printf(s, "Searched dev:%s\n", dbg->dev_name);
462                 seq_printf(s, "Searched state:%s\n", dbg->state_name);
463                 seq_printf(s, "Searched pin:%s\n", dbg->pin_name);
464                 seq_printf(s, "Use: modify config_pin <devname> "\
465                                 "<state> <pinname> <value>\n");
466                 goto exit;
467         }
468
469         pctldev = get_pinctrl_dev_from_devname(found->ctrl_dev_name);
470         config = *found->data.configs.configs;
471         seq_printf(s, "Dev %s has config of %s in state %s: 0x%08lX\n",
472                         dbg->dev_name, dbg->pin_name,
473                         dbg->state_name, config);
474
475         if (pctldev)
476                 confops = pctldev->desc->confops;
477
478         if (confops && confops->pin_config_config_dbg_show)
479                 confops->pin_config_config_dbg_show(pctldev, s, config);
480
481 exit:
482         mutex_unlock(&pinctrl_maps_mutex);
483
484         return 0;
485 }
486
487 /**
488  * pinconf_dbg_config_write() - modify the pinctrl config in the pinctrl
489  * map, of a dev/pin/state entry based on user entries to pinconf-config
490  * @user_buf: contains the modification request with expected format:
491  *     modify config_pin <devicename> <state> <pinname> <newvalue>
492  * modify is literal string, alternatives like add/delete not supported yet
493  * config_pin is literal, alternatives like config_mux not supported yet
494  * <devicename> <state> <pinname> are values that should match the pinctrl-maps
495  * <newvalue> reflects the new config and is driver dependant
496  */
497 static int pinconf_dbg_config_write(struct file *file,
498         const char __user *user_buf, size_t count, loff_t *ppos)
499 {
500         struct pinctrl_maps *maps_node;
501         const struct pinctrl_map *map;
502         const struct pinctrl_map *found = NULL;
503         struct pinctrl_dev *pctldev;
504         const struct pinconf_ops *confops = NULL;
505         struct dbg_cfg *dbg = &pinconf_dbg_conf;
506         const struct pinctrl_map_configs *configs;
507         char config[MAX_NAME_LEN+1];
508         char buf[128];
509         char *b = &buf[0];
510         int buf_size;
511         char *token;
512         int i;
513
514         /* Get userspace string and assure termination */
515         buf_size = min(count, (size_t)(sizeof(buf)-1));
516         if (copy_from_user(buf, user_buf, buf_size))
517                 return -EFAULT;
518         buf[buf_size] = 0;
519
520         /*
521          * need to parse entry and extract parameters:
522          * modify configs_pin devicename state pinname newvalue
523          */
524
525         /* Get arg: 'modify' */
526         token = strsep(&b, " ");
527         if (!token)
528                 return -EINVAL;
529         if (strcmp(token, "modify"))
530                 return -EINVAL;
531
532         /* Get arg type: "config_pin" type supported so far */
533         token = strsep(&b, " ");
534         if (!token)
535                 return -EINVAL;
536         if (strcmp(token, "config_pin"))
537                 return -EINVAL;
538         dbg->map_type = PIN_MAP_TYPE_CONFIGS_PIN;
539
540         /* get arg 'device_name' */
541         token = strsep(&b, " ");
542         if (token == NULL)
543                 return -EINVAL;
544         if (strlen(token) >= MAX_NAME_LEN)
545                 return -EINVAL;
546         strncpy(dbg->dev_name, token, MAX_NAME_LEN);
547
548         /* get arg 'state_name' */
549         token = strsep(&b, " ");
550         if (token == NULL)
551                 return -EINVAL;
552         if (strlen(token) >= MAX_NAME_LEN)
553                 return -EINVAL;
554         strncpy(dbg->state_name, token, MAX_NAME_LEN);
555
556         /* get arg 'pin_name' */
557         token = strsep(&b, " ");
558         if (token == NULL)
559                 return -EINVAL;
560         if (strlen(token) >= MAX_NAME_LEN)
561                 return -EINVAL;
562         strncpy(dbg->pin_name, token, MAX_NAME_LEN);
563
564         /* get new_value of config' */
565         token = strsep(&b, " ");
566         if (token == NULL)
567                 return -EINVAL;
568         if (strlen(token) >= MAX_NAME_LEN)
569                 return -EINVAL;
570         strncpy(config, token, MAX_NAME_LEN);
571
572         mutex_lock(&pinctrl_maps_mutex);
573
574         /* Parse the pinctrl map and look for the selected dev/state/pin */
575         for_each_maps(maps_node, i, map) {
576                 if (strcmp(map->dev_name, dbg->dev_name))
577                         continue;
578                 if (map->type != dbg->map_type)
579                         continue;
580                 if (strcmp(map->name, dbg->state_name))
581                         continue;
582
583                 /*  we found the right pin / state, so overwrite config */
584                 if (!strcmp(map->data.configs.group_or_pin, dbg->pin_name)) {
585                         found = map;
586                         break;
587                 }
588         }
589
590         if (!found) {
591                 count = -EINVAL;
592                 goto exit;
593         }
594
595         pctldev = get_pinctrl_dev_from_devname(found->ctrl_dev_name);
596         if (pctldev)
597                 confops = pctldev->desc->confops;
598
599         if (confops && confops->pin_config_dbg_parse_modify) {
600                 configs = &found->data.configs;
601                 for (i = 0; i < configs->num_configs; i++) {
602                         confops->pin_config_dbg_parse_modify(pctldev,
603                                                      config,
604                                                      &configs->configs[i]);
605                 }
606         }
607
608 exit:
609         mutex_unlock(&pinctrl_maps_mutex);
610
611         return count;
612 }
613
614 static int pinconf_dbg_config_open(struct inode *inode, struct file *file)
615 {
616         return single_open(file, pinconf_dbg_config_print, inode->i_private);
617 }
618
619 static const struct file_operations pinconf_dbg_pinconfig_fops = {
620         .open = pinconf_dbg_config_open,
621         .write = pinconf_dbg_config_write,
622         .read = seq_read,
623         .llseek = seq_lseek,
624         .release = single_release,
625         .owner = THIS_MODULE,
626 };
627
628 void pinconf_init_device_debugfs(struct dentry *devroot,
629                          struct pinctrl_dev *pctldev)
630 {
631         debugfs_create_file("pinconf-pins", S_IFREG | S_IRUGO,
632                             devroot, pctldev, &pinconf_pins_ops);
633         debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO,
634                             devroot, pctldev, &pinconf_groups_ops);
635         debugfs_create_file("pinconf-config",  (S_IRUGO | S_IWUSR | S_IWGRP),
636                             devroot, pctldev, &pinconf_dbg_pinconfig_fops);
637 }
638
639 #endif