1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2015  Masahiro Yamada <yamada.masahiro@socionext.com>
4  */
5 
6 #include <common.h>
7 #include <dm.h>
8 #include <dm/device_compat.h>
9 #include <linux/compat.h>
10 #include <dm/pinctrl.h>
11 
12 /**
13  * pinctrl_pin_name_to_selector() - return the pin selector for a pin
14  *
15  * @dev: pin controller device
16  * @pin: the pin name to look up
17  * @return: pin selector, or negative error code on failure
18  */
pinctrl_pin_name_to_selector(struct udevice * dev,const char * pin)19 static int pinctrl_pin_name_to_selector(struct udevice *dev, const char *pin)
20 {
21 	const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
22 	unsigned npins, selector;
23 
24 	if (!ops->get_pins_count || !ops->get_pin_name) {
25 		dev_dbg(dev, "get_pins_count or get_pin_name missing\n");
26 		return -ENOSYS;
27 	}
28 
29 	npins = ops->get_pins_count(dev);
30 
31 	/* See if this pctldev has this pin */
32 	for (selector = 0; selector < npins; selector++) {
33 		const char *pname = ops->get_pin_name(dev, selector);
34 
35 		if (!strcmp(pin, pname))
36 			return selector;
37 	}
38 
39 	return -ENOSYS;
40 }
41 
42 /**
43  * pinctrl_group_name_to_selector() - return the group selector for a group
44  *
45  * @dev: pin controller device
46  * @group: the pin group name to look up
47  * @return: pin group selector, or negative error code on failure
48  */
pinctrl_group_name_to_selector(struct udevice * dev,const char * group)49 static int pinctrl_group_name_to_selector(struct udevice *dev,
50 					  const char *group)
51 {
52 	const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
53 	unsigned ngroups, selector;
54 
55 	if (!ops->get_groups_count || !ops->get_group_name) {
56 		dev_dbg(dev, "get_groups_count or get_group_name missing\n");
57 		return -ENOSYS;
58 	}
59 
60 	ngroups = ops->get_groups_count(dev);
61 
62 	/* See if this pctldev has this group */
63 	for (selector = 0; selector < ngroups; selector++) {
64 		const char *gname = ops->get_group_name(dev, selector);
65 
66 		if (!strcmp(group, gname))
67 			return selector;
68 	}
69 
70 	return -ENOSYS;
71 }
72 
73 #if CONFIG_IS_ENABLED(PINMUX)
74 /**
75  * pinmux_func_name_to_selector() - return the function selector for a function
76  *
77  * @dev: pin controller device
78  * @function: the function name to look up
79  * @return: function selector, or negative error code on failure
80  */
pinmux_func_name_to_selector(struct udevice * dev,const char * function)81 static int pinmux_func_name_to_selector(struct udevice *dev,
82 					const char *function)
83 {
84 	const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
85 	unsigned nfuncs, selector = 0;
86 
87 	if (!ops->get_functions_count || !ops->get_function_name) {
88 		dev_dbg(dev,
89 			"get_functions_count or get_function_name missing\n");
90 		return -ENOSYS;
91 	}
92 
93 	nfuncs = ops->get_functions_count(dev);
94 
95 	/* See if this pctldev has this function */
96 	for (selector = 0; selector < nfuncs; selector++) {
97 		const char *fname = ops->get_function_name(dev, selector);
98 
99 		if (!strcmp(function, fname))
100 			return selector;
101 	}
102 
103 	return -ENOSYS;
104 }
105 
106 /**
107  * pinmux_enable_setting() - enable pin-mux setting for a certain pin/group
108  *
109  * @dev: pin controller device
110  * @is_group: target of operation (true: pin group, false: pin)
111  * @selector: pin selector or group selector, depending on @is_group
112  * @func_selector: function selector
113  * @return: 0 on success, or negative error code on failure
114  */
pinmux_enable_setting(struct udevice * dev,bool is_group,unsigned selector,unsigned func_selector)115 static int pinmux_enable_setting(struct udevice *dev, bool is_group,
116 				 unsigned selector, unsigned func_selector)
117 {
118 	const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
119 
120 	if (is_group) {
121 		if (!ops->pinmux_group_set) {
122 			dev_dbg(dev, "pinmux_group_set op missing\n");
123 			return -ENOSYS;
124 		}
125 
126 		return ops->pinmux_group_set(dev, selector, func_selector);
127 	} else {
128 		if (!ops->pinmux_set) {
129 			dev_dbg(dev, "pinmux_set op missing\n");
130 			return -ENOSYS;
131 		}
132 		return ops->pinmux_set(dev, selector, func_selector);
133 	}
134 }
135 #else
pinmux_func_name_to_selector(struct udevice * dev,const char * function)136 static int pinmux_func_name_to_selector(struct udevice *dev,
137 					const char *function)
138 {
139 	return 0;
140 }
141 
pinmux_enable_setting(struct udevice * dev,bool is_group,unsigned selector,unsigned func_selector)142 static int pinmux_enable_setting(struct udevice *dev, bool is_group,
143 				 unsigned selector, unsigned func_selector)
144 {
145 	return 0;
146 }
147 #endif
148 
149 #if CONFIG_IS_ENABLED(PINCONF)
150 /**
151  * pinconf_prop_name_to_param() - return parameter ID for a property name
152  *
153  * @dev: pin controller device
154  * @property: property name in DTS, such as "bias-pull-up", "slew-rate", etc.
155  * @default_value: return default value in case no value is specified in DTS
156  * @return: return pamater ID, or negative error code on failure
157  */
pinconf_prop_name_to_param(struct udevice * dev,const char * property,u32 * default_value)158 static int pinconf_prop_name_to_param(struct udevice *dev,
159 				      const char *property, u32 *default_value)
160 {
161 	const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
162 	const struct pinconf_param *p, *end;
163 
164 	if (!ops->pinconf_num_params || !ops->pinconf_params) {
165 		dev_dbg(dev, "pinconf_num_params or pinconf_params missing\n");
166 		return -ENOSYS;
167 	}
168 
169 	p = ops->pinconf_params;
170 	end = p + ops->pinconf_num_params;
171 
172 	/* See if this pctldev supports this parameter */
173 	for (; p < end; p++) {
174 		if (!strcmp(property, p->property)) {
175 			*default_value = p->default_value;
176 			return p->param;
177 		}
178 	}
179 
180 	return -ENOSYS;
181 }
182 
183 /**
184  * pinconf_enable_setting() - apply pin configuration for a certain pin/group
185  *
186  * @dev: pin controller device
187  * @is_group: target of operation (true: pin group, false: pin)
188  * @selector: pin selector or group selector, depending on @is_group
189  * @param: configuration paramter
190  * @argument: argument taken by some configuration parameters
191  * @return: 0 on success, or negative error code on failure
192  */
pinconf_enable_setting(struct udevice * dev,bool is_group,unsigned selector,unsigned param,u32 argument)193 static int pinconf_enable_setting(struct udevice *dev, bool is_group,
194 				  unsigned selector, unsigned param,
195 				  u32 argument)
196 {
197 	const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
198 
199 	if (is_group) {
200 		if (!ops->pinconf_group_set) {
201 			dev_dbg(dev, "pinconf_group_set op missing\n");
202 			return -ENOSYS;
203 		}
204 
205 		return ops->pinconf_group_set(dev, selector, param,
206 					      argument);
207 	} else {
208 		if (!ops->pinconf_set) {
209 			dev_dbg(dev, "pinconf_set op missing\n");
210 			return -ENOSYS;
211 		}
212 		return ops->pinconf_set(dev, selector, param, argument);
213 	}
214 }
215 #else
pinconf_prop_name_to_param(struct udevice * dev,const char * property,u32 * default_value)216 static int pinconf_prop_name_to_param(struct udevice *dev,
217 				      const char *property, u32 *default_value)
218 {
219 	return -ENOSYS;
220 }
221 
pinconf_enable_setting(struct udevice * dev,bool is_group,unsigned selector,unsigned param,u32 argument)222 static int pinconf_enable_setting(struct udevice *dev, bool is_group,
223 				  unsigned selector, unsigned param,
224 				  u32 argument)
225 {
226 	return 0;
227 }
228 #endif
229 
230 enum pinmux_subnode_type {
231 	PST_NONE = 0,
232 	PST_PIN,
233 	PST_GROUP,
234 	PST_PINMUX,
235 };
236 
237 /**
238  * pinctrl_generic_set_state_one() - set state for a certain pin/group
239  * Apply all pin multiplexing and pin configurations specified by @config
240  * for a given pin or pin group.
241  *
242  * @dev: pin controller device
243  * @config: pseudo device pointing to config node
244  * @subnode_type: target of operation (pin, group, or pin specified by a pinmux
245  * group)
246  * @selector: pin selector or group selector, depending on @subnode_type
247  * @return: 0 on success, or negative error code on failure
248  */
pinctrl_generic_set_state_one(struct udevice * dev,struct udevice * config,enum pinmux_subnode_type subnode_type,unsigned selector)249 static int pinctrl_generic_set_state_one(struct udevice *dev,
250 					 struct udevice *config,
251 					 enum pinmux_subnode_type subnode_type,
252 					 unsigned selector)
253 {
254 	const char *propname;
255 	const void *value;
256 	struct ofprop property;
257 	int len, func_selector, param, ret;
258 	u32 arg, default_val;
259 
260 	assert(subnode_type != PST_NONE);
261 
262 	dev_for_each_property(property, config) {
263 		value = dev_read_prop_by_prop(&property, &propname, &len);
264 		if (!value)
265 			return -EINVAL;
266 
267 		/* pinmux subnodes already have their muxing set */
268 		if (subnode_type != PST_PINMUX &&
269 		    !strcmp(propname, "function")) {
270 			func_selector = pinmux_func_name_to_selector(dev,
271 								     value);
272 			if (func_selector < 0)
273 				return func_selector;
274 			ret = pinmux_enable_setting(dev,
275 						    subnode_type == PST_GROUP,
276 						    selector,
277 						    func_selector);
278 		} else {
279 			param = pinconf_prop_name_to_param(dev, propname,
280 							   &default_val);
281 			if (param < 0)
282 				continue; /* just skip unknown properties */
283 
284 			if (len >= sizeof(fdt32_t))
285 				arg = fdt32_to_cpu(*(fdt32_t *)value);
286 			else
287 				arg = default_val;
288 
289 			ret = pinconf_enable_setting(dev,
290 						     subnode_type == PST_GROUP,
291 						     selector, param, arg);
292 		}
293 
294 		if (ret)
295 			return ret;
296 	}
297 
298 	return 0;
299 }
300 
301 /**
302  * pinctrl_generic_get_subnode_type() - determine whether there is a valid
303  * pins, groups, or pinmux property in the config node
304  *
305  * @dev: pin controller device
306  * @config: pseudo device pointing to config node
307  * @count: number of specifiers contained within the property
308  * @return: the type of the subnode, or PST_NONE
309  */
pinctrl_generic_get_subnode_type(struct udevice * dev,struct udevice * config,int * count)310 static enum pinmux_subnode_type pinctrl_generic_get_subnode_type(struct udevice *dev,
311 								 struct udevice *config,
312 								 int *count)
313 {
314 	const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
315 
316 	*count = dev_read_string_count(config, "pins");
317 	if (*count >= 0)
318 		return PST_PIN;
319 
320 	*count = dev_read_string_count(config, "groups");
321 	if (*count >= 0)
322 		return PST_GROUP;
323 
324 	if (ops->pinmux_property_set) {
325 		*count = dev_read_size(config, "pinmux");
326 		if (*count >= 0 && !(*count % sizeof(u32))) {
327 			*count /= sizeof(u32);
328 			return PST_PINMUX;
329 		}
330 	}
331 
332 	*count = 0;
333 	return PST_NONE;
334 }
335 
336 /**
337  * pinctrl_generic_set_state_subnode() - apply all settings in config node
338  *
339  * @dev: pin controller device
340  * @config: pseudo device pointing to config node
341  * @return: 0 on success, or negative error code on failure
342  */
pinctrl_generic_set_state_subnode(struct udevice * dev,struct udevice * config)343 static int pinctrl_generic_set_state_subnode(struct udevice *dev,
344 					     struct udevice *config)
345 {
346 	enum pinmux_subnode_type subnode_type;
347 	const char *name;
348 	int count, selector, i, ret, scratch;
349 	const u32 *pinmux_groups = NULL; /* prevent use-uninitialized warning */
350 
351 	subnode_type = pinctrl_generic_get_subnode_type(dev, config, &count);
352 
353 	debug("%s(%s, %s): count=%d\n", __func__, dev->name, config->name,
354 	      count);
355 
356 	if (subnode_type == PST_PINMUX) {
357 		pinmux_groups = dev_read_prop(config, "pinmux", &scratch);
358 		if (!pinmux_groups)
359 			return -EINVAL;
360 	}
361 
362 	for (i = 0; i < count; i++) {
363 		switch (subnode_type) {
364 		case PST_PIN:
365 			ret = dev_read_string_index(config, "pins", i, &name);
366 			if (ret)
367 				return ret;
368 			selector = pinctrl_pin_name_to_selector(dev, name);
369 			break;
370 		case PST_GROUP:
371 			ret = dev_read_string_index(config, "groups", i, &name);
372 			if (ret)
373 				return ret;
374 			selector = pinctrl_group_name_to_selector(dev, name);
375 			break;
376 		case PST_PINMUX: {
377 			const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
378 			u32 pinmux_group = fdt32_to_cpu(pinmux_groups[i]);
379 
380 			/* Checked for in pinctrl_generic_get_subnode_type */
381 			selector = ops->pinmux_property_set(dev, pinmux_group);
382 			break;
383 		}
384 		case PST_NONE:
385 		default:
386 			/* skip this node; may contain config child nodes */
387 			return 0;
388 		}
389 
390 		if (selector < 0)
391 			return selector;
392 
393 		ret = pinctrl_generic_set_state_one(dev, config, subnode_type,
394 						    selector);
395 		if (ret)
396 			return ret;
397 	}
398 
399 	return 0;
400 }
401 
pinctrl_generic_set_state(struct udevice * dev,struct udevice * config)402 int pinctrl_generic_set_state(struct udevice *dev, struct udevice *config)
403 {
404 	struct udevice *child;
405 	int ret;
406 
407 	ret = pinctrl_generic_set_state_subnode(dev, config);
408 	if (ret)
409 		return ret;
410 
411 	for (device_find_first_child(config, &child);
412 	     child;
413 	     device_find_next_child(&child)) {
414 		ret = pinctrl_generic_set_state_subnode(dev, child);
415 		if (ret)
416 			return ret;
417 	}
418 
419 	return 0;
420 }
421