]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/pinctrl/pinconf-generic.c
pinctrl: add pinconf-generic define for a pin-default pull
[karo-tx-linux.git] / drivers / pinctrl / pinconf-generic.c
1 /*
2  * Core driver for the generic 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
12 #define pr_fmt(fmt) "generic pinconfig core: " fmt
13
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/device.h>
18 #include <linux/slab.h>
19 #include <linux/debugfs.h>
20 #include <linux/seq_file.h>
21 #include <linux/pinctrl/pinctrl.h>
22 #include <linux/pinctrl/pinconf.h>
23 #include <linux/pinctrl/pinconf-generic.h>
24 #include "core.h"
25 #include "pinconf.h"
26
27 #ifdef CONFIG_DEBUG_FS
28
29 struct pin_config_item {
30         const enum pin_config_param param;
31         const char * const display;
32         const char * const format;
33 };
34
35 #define PCONFDUMP(a, b, c) { .param = a, .display = b, .format = c }
36
37 static struct pin_config_item conf_items[] = {
38         PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL),
39         PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL),
40         PCONFDUMP(PIN_CONFIG_BIAS_BUS_HOLD, "input bias bus hold", NULL),
41         PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL),
42         PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", NULL),
43         PCONFDUMP(PIN_CONFIG_BIAS_PULL_PIN_DEFAULT,
44                                 "input bias pull to pin specific state", NULL),
45         PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL),
46         PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL),
47         PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL),
48         PCONFDUMP(PIN_CONFIG_DRIVE_STRENGTH, "output drive strength", "mA"),
49         PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_ENABLE, "input schmitt enabled", NULL),
50         PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL),
51         PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "time units"),
52         PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector"),
53         PCONFDUMP(PIN_CONFIG_SLEW_RATE, "slew rate", NULL),
54         PCONFDUMP(PIN_CONFIG_LOW_POWER_MODE, "pin low power", "mode"),
55         PCONFDUMP(PIN_CONFIG_OUTPUT, "pin output", "level"),
56 };
57
58 void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,
59                               struct seq_file *s, unsigned pin)
60 {
61         const struct pinconf_ops *ops = pctldev->desc->confops;
62         int i;
63
64         if (!ops->is_generic)
65                 return;
66
67         for (i = 0; i < ARRAY_SIZE(conf_items); i++) {
68                 unsigned long config;
69                 int ret;
70
71                 /* We want to check out this parameter */
72                 config = pinconf_to_config_packed(conf_items[i].param, 0);
73                 ret = pin_config_get_for_pin(pctldev, pin, &config);
74                 /* These are legal errors */
75                 if (ret == -EINVAL || ret == -ENOTSUPP)
76                         continue;
77                 if (ret) {
78                         seq_printf(s, "ERROR READING CONFIG SETTING %d ", i);
79                         continue;
80                 }
81                 /* Space between multiple configs */
82                 seq_puts(s, " ");
83                 seq_puts(s, conf_items[i].display);
84                 /* Print unit if available */
85                 if (conf_items[i].format &&
86                     pinconf_to_config_argument(config) != 0)
87                         seq_printf(s, " (%u %s)",
88                                    pinconf_to_config_argument(config),
89                                    conf_items[i].format);
90         }
91 }
92
93 void pinconf_generic_dump_group(struct pinctrl_dev *pctldev,
94                               struct seq_file *s, const char *gname)
95 {
96         const struct pinconf_ops *ops = pctldev->desc->confops;
97         int i;
98
99         if (!ops->is_generic)
100                 return;
101
102         for (i = 0; i < ARRAY_SIZE(conf_items); i++) {
103                 unsigned long config;
104                 int ret;
105
106                 /* We want to check out this parameter */
107                 config = pinconf_to_config_packed(conf_items[i].param, 0);
108                 ret = pin_config_group_get(dev_name(pctldev->dev), gname,
109                                            &config);
110                 /* These are legal errors */
111                 if (ret == -EINVAL || ret == -ENOTSUPP)
112                         continue;
113                 if (ret) {
114                         seq_printf(s, "ERROR READING CONFIG SETTING %d ", i);
115                         continue;
116                 }
117                 /* Space between multiple configs */
118                 seq_puts(s, " ");
119                 seq_puts(s, conf_items[i].display);
120                 /* Print unit if available */
121                 if (conf_items[i].format && config != 0)
122                         seq_printf(s, " (%u %s)",
123                                    pinconf_to_config_argument(config),
124                                    conf_items[i].format);
125         }
126 }
127
128 void pinconf_generic_dump_config(struct pinctrl_dev *pctldev,
129                                  struct seq_file *s, unsigned long config)
130 {
131         int i;
132
133         for (i = 0; i < ARRAY_SIZE(conf_items); i++) {
134                 if (pinconf_to_config_param(config) != conf_items[i].param)
135                         continue;
136                 seq_printf(s, "%s: 0x%x", conf_items[i].display,
137                            pinconf_to_config_argument(config));
138         }
139 }
140 EXPORT_SYMBOL_GPL(pinconf_generic_dump_config);
141 #endif