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 /drivers/pinctrl/pinconf-generic.c | |
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>
Diffstat (limited to 'drivers/pinctrl/pinconf-generic.c')
-rw-r--r-- | drivers/pinctrl/pinconf-generic.c | 81 |
1 files changed, 81 insertions, 0 deletions
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 | ||