diff options
author | Heiko Stübner <heiko@sntech.de> | 2013-06-10 15:40:29 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2013-06-16 05:57:32 -0400 |
commit | 7db9af4b6e41be599e0fcd50d687138a5add428c (patch) | |
tree | 222803dcf9b69980bf4398fc203b832dc2b1a6c8 | |
parent | 5c0e3580cb988cf4688070d2d7ac56cf83fc6959 (diff) |
pinctrl: add function to parse generic pinconfig properties from a dt node
pinconf_generic_parse_dt_config() takes a node as input and generates an
array of generic pinconfig values from the properties of this node.
As I couldn't find a mechanism to count the number of properties of a node
the function uses internally an array to accept one of parameter and copies
the real present options to a smaller variable at its end.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt | 38 | ||||
-rw-r--r-- | drivers/pinctrl/pinconf-generic.c | 81 | ||||
-rw-r--r-- | drivers/pinctrl/pinconf.h | 6 |
3 files changed, 125 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt index c95ea8278f87..ef7cd572214c 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt | |||
@@ -126,3 +126,41 @@ device; they may be grandchildren, for example. Whether this is legal, and | |||
126 | whether there is any interaction between the child and intermediate parent | 126 | whether there is any interaction between the child and intermediate parent |
127 | nodes, is again defined entirely by the binding for the individual pin | 127 | nodes, is again defined entirely by the binding for the individual pin |
128 | controller device. | 128 | controller device. |
129 | |||
130 | == Using generic pinconfig options == | ||
131 | |||
132 | Generic pinconfig parameters can be used by defining a separate node containing | ||
133 | the applicable parameters (and optional values), like: | ||
134 | |||
135 | pcfg_pull_up: pcfg_pull_up { | ||
136 | bias-pull-up; | ||
137 | drive-strength = <20>; | ||
138 | }; | ||
139 | |||
140 | This node should then be referenced in the appropriate pinctrl node as a phandle | ||
141 | and parsed in the driver using the pinconf_generic_parse_dt_config function. | ||
142 | |||
143 | Supported configuration parameters are: | ||
144 | |||
145 | bias-disable - disable any pin bias | ||
146 | bias-high-impedance - high impedance mode ("third-state", "floating") | ||
147 | bias-bus-hold - latch weakly | ||
148 | bias-pull-up - pull up the pin | ||
149 | bias-pull-down - pull down the pin | ||
150 | bias-pull-pin-default - use pin-default pull state | ||
151 | drive-push-pull - drive actively high and low | ||
152 | drive-open-drain - drive with open drain | ||
153 | drive-open-source - drive with open source | ||
154 | drive-strength - sink or source at most X mA | ||
155 | input-schmitt-enable - enable schmitt-trigger mode | ||
156 | input-schmitt-disable - disable schmitt-trigger mode | ||
157 | input-schmitt - run in schmitt-trigger mode with hysteresis X | ||
158 | input-debounce - debounce mode with debound time X | ||
159 | power-source - select power source X | ||
160 | slew-rate - use slew-rate X | ||
161 | low-power-mode - low power mode | ||
162 | output-low - set the pin to output mode with low level | ||
163 | output-high - set the pin to output mode with high level | ||
164 | |||
165 | More in-depth documentation on these parameters can be found in | ||
166 | <include/linux/pinctrl/pinconfig-generic.h> | ||
diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index 9a6812b50a32..d3c693c0c250 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/pinctrl/pinctrl.h> | 21 | #include <linux/pinctrl/pinctrl.h> |
22 | #include <linux/pinctrl/pinconf.h> | 22 | #include <linux/pinctrl/pinconf.h> |
23 | #include <linux/pinctrl/pinconf-generic.h> | 23 | #include <linux/pinctrl/pinconf-generic.h> |
24 | #include <linux/of.h> | ||
24 | #include "core.h" | 25 | #include "core.h" |
25 | #include "pinconf.h" | 26 | #include "pinconf.h" |
26 | 27 | ||
@@ -139,3 +140,83 @@ void pinconf_generic_dump_config(struct pinctrl_dev *pctldev, | |||
139 | } | 140 | } |
140 | EXPORT_SYMBOL_GPL(pinconf_generic_dump_config); | 141 | EXPORT_SYMBOL_GPL(pinconf_generic_dump_config); |
141 | #endif | 142 | #endif |
143 | |||
144 | #ifdef CONFIG_OF | ||
145 | struct pinconf_generic_dt_params { | ||
146 | const char * const property; | ||
147 | enum pin_config_param param; | ||
148 | u32 default_value; | ||
149 | }; | ||
150 | |||
151 | static struct pinconf_generic_dt_params dt_params[] = { | ||
152 | { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, | ||
153 | { "bias-high-impedance", PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0 }, | ||
154 | { "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 }, | ||
155 | { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 0 }, | ||
156 | { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 0 }, | ||
157 | { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 0 }, | ||
158 | { "drive-push-pull", PIN_CONFIG_DRIVE_PUSH_PULL, 0 }, | ||
159 | { "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 }, | ||
160 | { "drive-open-source", PIN_CONFIG_DRIVE_OPEN_SOURCE, 0 }, | ||
161 | { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 }, | ||
162 | { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 }, | ||
163 | { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 }, | ||
164 | { "input-schmitt", PIN_CONFIG_INPUT_SCHMITT, 0 }, | ||
165 | { "input-debounce", PIN_CONFIG_INPUT_DEBOUNCE, 0 }, | ||
166 | { "power-source", PIN_CONFIG_POWER_SOURCE, 0 }, | ||
167 | { "slew-rate", PIN_CONFIG_SLEW_RATE, 0 }, | ||
168 | { "low-power-mode", PIN_CONFIG_LOW_POWER_MODE, 0 }, | ||
169 | { "output-low", PIN_CONFIG_OUTPUT, 0, }, | ||
170 | { "output-high", PIN_CONFIG_OUTPUT, 1, }, | ||
171 | }; | ||
172 | |||
173 | /** | ||
174 | * pinconf_generic_parse_dt_config() | ||
175 | * parse the config properties into generic pinconfig values. | ||
176 | * @np: node containing the pinconfig properties | ||
177 | * @configs: array with nconfigs entries containing the generic pinconf values | ||
178 | * @nconfigs: umber of configurations | ||
179 | */ | ||
180 | int pinconf_generic_parse_dt_config(struct device_node *np, | ||
181 | unsigned long **configs, | ||
182 | unsigned int *nconfigs) | ||
183 | { | ||
184 | unsigned long cfg[ARRAY_SIZE(dt_params)]; | ||
185 | unsigned int ncfg = 0; | ||
186 | int ret; | ||
187 | int i; | ||
188 | u32 val; | ||
189 | |||
190 | if (!np) | ||
191 | return -EINVAL; | ||
192 | |||
193 | for (i = 0; i < ARRAY_SIZE(dt_params); i++) { | ||
194 | struct pinconf_generic_dt_params *par = &dt_params[i]; | ||
195 | ret = of_property_read_u32(np, par->property, &val); | ||
196 | |||
197 | /* property not found */ | ||
198 | if (ret == -EINVAL) | ||
199 | continue; | ||
200 | |||
201 | /* use default value, when no value is specified */ | ||
202 | if (ret) | ||
203 | val = par->default_value; | ||
204 | |||
205 | pr_debug("found %s with value %u\n", par->property, val); | ||
206 | cfg[ncfg] = pinconf_to_config_packed(par->param, val); | ||
207 | ncfg++; | ||
208 | } | ||
209 | |||
210 | /* | ||
211 | * Now limit the number of configs to the real number of | ||
212 | * found properties. | ||
213 | */ | ||
214 | *configs = kzalloc(ncfg * sizeof(unsigned long), GFP_KERNEL); | ||
215 | if (!*configs) | ||
216 | return -ENOMEM; | ||
217 | |||
218 | memcpy(*configs, &cfg, ncfg * sizeof(unsigned long)); | ||
219 | *nconfigs = ncfg; | ||
220 | return 0; | ||
221 | } | ||
222 | #endif | ||
diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h index 92c7267244d2..a4a5417e1413 100644 --- a/drivers/pinctrl/pinconf.h +++ b/drivers/pinctrl/pinconf.h | |||
@@ -123,3 +123,9 @@ static inline void pinconf_generic_dump_config(struct pinctrl_dev *pctldev, | |||
123 | return; | 123 | return; |
124 | } | 124 | } |
125 | #endif | 125 | #endif |
126 | |||
127 | #if defined(CONFIG_GENERIC_PINCONF) && defined(CONFIG_OF) | ||
128 | int pinconf_generic_parse_dt_config(struct device_node *np, | ||
129 | unsigned long **configs, | ||
130 | unsigned int *nconfigs); | ||
131 | #endif | ||