xref: /openbmc/linux/drivers/pinctrl/pinconf.c (revision ae40e94f)
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/pinctrl/machine.h>
21 #include <linux/pinctrl/pinctrl.h>
22 #include <linux/pinctrl/pinconf.h>
23 #include "core.h"
24 #include "pinconf.h"
25 
26 int pinconf_check_ops(struct pinctrl_dev *pctldev)
27 {
28 	const struct pinconf_ops *ops = pctldev->desc->confops;
29 
30 	/* We have to be able to config the pins in SOME way */
31 	if (!ops->pin_config_set && !ops->pin_config_group_set) {
32 		dev_err(pctldev->dev,
33 			"pinconf has to be able to set a pins config\n");
34 		return -EINVAL;
35 	}
36 	return 0;
37 }
38 
39 int pinconf_validate_map(const struct pinctrl_map *map, int i)
40 {
41 	if (!map->data.configs.group_or_pin) {
42 		pr_err("failed to register map %s (%d): no group/pin given\n",
43 		       map->name, i);
44 		return -EINVAL;
45 	}
46 
47 	if (!map->data.configs.num_configs ||
48 			!map->data.configs.configs) {
49 		pr_err("failed to register map %s (%d): no configs given\n",
50 		       map->name, i);
51 		return -EINVAL;
52 	}
53 
54 	return 0;
55 }
56 
57 int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
58 			   unsigned long *config)
59 {
60 	const struct pinconf_ops *ops = pctldev->desc->confops;
61 
62 	if (!ops || !ops->pin_config_get) {
63 		dev_dbg(pctldev->dev,
64 			"cannot get pin configuration, .pin_config_get missing in driver\n");
65 		return -ENOTSUPP;
66 	}
67 
68 	return ops->pin_config_get(pctldev, pin, config);
69 }
70 
71 int pin_config_group_get(const char *dev_name, const char *pin_group,
72 			 unsigned long *config)
73 {
74 	struct pinctrl_dev *pctldev;
75 	const struct pinconf_ops *ops;
76 	int selector, ret;
77 
78 	pctldev = get_pinctrl_dev_from_devname(dev_name);
79 	if (!pctldev) {
80 		ret = -EINVAL;
81 		return ret;
82 	}
83 
84 	mutex_lock(&pctldev->mutex);
85 
86 	ops = pctldev->desc->confops;
87 
88 	if (!ops || !ops->pin_config_group_get) {
89 		dev_dbg(pctldev->dev,
90 			"cannot get configuration for pin group, missing group config get function in driver\n");
91 		ret = -ENOTSUPP;
92 		goto unlock;
93 	}
94 
95 	selector = pinctrl_get_group_selector(pctldev, pin_group);
96 	if (selector < 0) {
97 		ret = selector;
98 		goto unlock;
99 	}
100 
101 	ret = ops->pin_config_group_get(pctldev, selector, config);
102 
103 unlock:
104 	mutex_unlock(&pctldev->mutex);
105 	return ret;
106 }
107 
108 int pinconf_map_to_setting(const struct pinctrl_map *map,
109 			  struct pinctrl_setting *setting)
110 {
111 	struct pinctrl_dev *pctldev = setting->pctldev;
112 	int pin;
113 
114 	switch (setting->type) {
115 	case PIN_MAP_TYPE_CONFIGS_PIN:
116 		pin = pin_get_from_name(pctldev,
117 					map->data.configs.group_or_pin);
118 		if (pin < 0) {
119 			dev_err(pctldev->dev, "could not map pin config for \"%s\"",
120 				map->data.configs.group_or_pin);
121 			return pin;
122 		}
123 		setting->data.configs.group_or_pin = pin;
124 		break;
125 	case PIN_MAP_TYPE_CONFIGS_GROUP:
126 		pin = pinctrl_get_group_selector(pctldev,
127 					 map->data.configs.group_or_pin);
128 		if (pin < 0) {
129 			dev_err(pctldev->dev, "could not map group config for \"%s\"",
130 				map->data.configs.group_or_pin);
131 			return pin;
132 		}
133 		setting->data.configs.group_or_pin = pin;
134 		break;
135 	default:
136 		return -EINVAL;
137 	}
138 
139 	setting->data.configs.num_configs = map->data.configs.num_configs;
140 	setting->data.configs.configs = map->data.configs.configs;
141 
142 	return 0;
143 }
144 
145 void pinconf_free_setting(const struct pinctrl_setting *setting)
146 {
147 }
148 
149 int pinconf_apply_setting(const struct pinctrl_setting *setting)
150 {
151 	struct pinctrl_dev *pctldev = setting->pctldev;
152 	const struct pinconf_ops *ops = pctldev->desc->confops;
153 	int ret;
154 
155 	if (!ops) {
156 		dev_err(pctldev->dev, "missing confops\n");
157 		return -EINVAL;
158 	}
159 
160 	switch (setting->type) {
161 	case PIN_MAP_TYPE_CONFIGS_PIN:
162 		if (!ops->pin_config_set) {
163 			dev_err(pctldev->dev, "missing pin_config_set op\n");
164 			return -EINVAL;
165 		}
166 		ret = ops->pin_config_set(pctldev,
167 				setting->data.configs.group_or_pin,
168 				setting->data.configs.configs,
169 				setting->data.configs.num_configs);
170 		if (ret < 0) {
171 			dev_err(pctldev->dev,
172 				"pin_config_set op failed for pin %d\n",
173 				setting->data.configs.group_or_pin);
174 			return ret;
175 		}
176 		break;
177 	case PIN_MAP_TYPE_CONFIGS_GROUP:
178 		if (!ops->pin_config_group_set) {
179 			dev_err(pctldev->dev,
180 				"missing pin_config_group_set op\n");
181 			return -EINVAL;
182 		}
183 		ret = ops->pin_config_group_set(pctldev,
184 				setting->data.configs.group_or_pin,
185 				setting->data.configs.configs,
186 				setting->data.configs.num_configs);
187 		if (ret < 0) {
188 			dev_err(pctldev->dev,
189 				"pin_config_group_set op failed for group %d\n",
190 				setting->data.configs.group_or_pin);
191 			return ret;
192 		}
193 		break;
194 	default:
195 		return -EINVAL;
196 	}
197 
198 	return 0;
199 }
200 
201 int pinconf_set_config(struct pinctrl_dev *pctldev, unsigned pin,
202 		       unsigned long *configs, size_t nconfigs)
203 {
204 	const struct pinconf_ops *ops;
205 
206 	ops = pctldev->desc->confops;
207 	if (!ops || !ops->pin_config_set)
208 		return -ENOTSUPP;
209 
210 	return ops->pin_config_set(pctldev, pin, configs, nconfigs);
211 }
212 
213 #ifdef CONFIG_DEBUG_FS
214 
215 static void pinconf_show_config(struct seq_file *s, struct pinctrl_dev *pctldev,
216 		      unsigned long *configs, unsigned num_configs)
217 {
218 	const struct pinconf_ops *confops;
219 	int i;
220 
221 	if (pctldev)
222 		confops = pctldev->desc->confops;
223 	else
224 		confops = NULL;
225 
226 	for (i = 0; i < num_configs; i++) {
227 		seq_puts(s, "config ");
228 		if (confops && confops->pin_config_config_dbg_show)
229 			confops->pin_config_config_dbg_show(pctldev, s,
230 							    configs[i]);
231 		else
232 			seq_printf(s, "%08lx", configs[i]);
233 		seq_putc(s, '\n');
234 	}
235 }
236 
237 void pinconf_show_map(struct seq_file *s, const struct pinctrl_map *map)
238 {
239 	struct pinctrl_dev *pctldev;
240 
241 	pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
242 
243 	switch (map->type) {
244 	case PIN_MAP_TYPE_CONFIGS_PIN:
245 		seq_puts(s, "pin ");
246 		break;
247 	case PIN_MAP_TYPE_CONFIGS_GROUP:
248 		seq_puts(s, "group ");
249 		break;
250 	default:
251 		break;
252 	}
253 
254 	seq_printf(s, "%s\n", map->data.configs.group_or_pin);
255 
256 	pinconf_show_config(s, pctldev, map->data.configs.configs,
257 			    map->data.configs.num_configs);
258 }
259 
260 void pinconf_show_setting(struct seq_file *s,
261 			  const struct pinctrl_setting *setting)
262 {
263 	struct pinctrl_dev *pctldev = setting->pctldev;
264 	const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
265 	struct pin_desc *desc;
266 
267 	switch (setting->type) {
268 	case PIN_MAP_TYPE_CONFIGS_PIN:
269 		desc = pin_desc_get(setting->pctldev,
270 				    setting->data.configs.group_or_pin);
271 		seq_printf(s, "pin %s (%d)", desc->name,
272 			   setting->data.configs.group_or_pin);
273 		break;
274 	case PIN_MAP_TYPE_CONFIGS_GROUP:
275 		seq_printf(s, "group %s (%d)",
276 			   pctlops->get_group_name(pctldev,
277 					setting->data.configs.group_or_pin),
278 			   setting->data.configs.group_or_pin);
279 		break;
280 	default:
281 		break;
282 	}
283 
284 	/*
285 	 * FIXME: We should really get the pin controller to dump the config
286 	 * values, so they can be decoded to something meaningful.
287 	 */
288 	pinconf_show_config(s, pctldev, setting->data.configs.configs,
289 			    setting->data.configs.num_configs);
290 }
291 
292 static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
293 			     struct seq_file *s, int pin)
294 {
295 	const struct pinconf_ops *ops = pctldev->desc->confops;
296 
297 	/* no-op when not using generic pin config */
298 	pinconf_generic_dump_pins(pctldev, s, NULL, pin);
299 	if (ops && ops->pin_config_dbg_show)
300 		ops->pin_config_dbg_show(pctldev, s, pin);
301 }
302 
303 static int pinconf_pins_show(struct seq_file *s, void *what)
304 {
305 	struct pinctrl_dev *pctldev = s->private;
306 	unsigned i, pin;
307 
308 	seq_puts(s, "Pin config settings per pin\n");
309 	seq_puts(s, "Format: pin (name): configs\n");
310 
311 	mutex_lock(&pctldev->mutex);
312 
313 	/* The pin number can be retrived from the pin controller descriptor */
314 	for (i = 0; i < pctldev->desc->npins; i++) {
315 		struct pin_desc *desc;
316 
317 		pin = pctldev->desc->pins[i].number;
318 		desc = pin_desc_get(pctldev, pin);
319 		/* Skip if we cannot search the pin */
320 		if (!desc)
321 			continue;
322 
323 		seq_printf(s, "pin %d (%s): ", pin, desc->name);
324 
325 		pinconf_dump_pin(pctldev, s, pin);
326 		seq_putc(s, '\n');
327 	}
328 
329 	mutex_unlock(&pctldev->mutex);
330 
331 	return 0;
332 }
333 
334 static void pinconf_dump_group(struct pinctrl_dev *pctldev,
335 			       struct seq_file *s, unsigned selector,
336 			       const char *gname)
337 {
338 	const struct pinconf_ops *ops = pctldev->desc->confops;
339 
340 	/* no-op when not using generic pin config */
341 	pinconf_generic_dump_pins(pctldev, s, gname, 0);
342 	if (ops && ops->pin_config_group_dbg_show)
343 		ops->pin_config_group_dbg_show(pctldev, s, selector);
344 }
345 
346 static int pinconf_groups_show(struct seq_file *s, void *what)
347 {
348 	struct pinctrl_dev *pctldev = s->private;
349 	const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
350 	unsigned ngroups = pctlops->get_groups_count(pctldev);
351 	unsigned selector = 0;
352 
353 	seq_puts(s, "Pin config settings per pin group\n");
354 	seq_puts(s, "Format: group (name): configs\n");
355 
356 	while (selector < ngroups) {
357 		const char *gname = pctlops->get_group_name(pctldev, selector);
358 
359 		seq_printf(s, "%u (%s): ", selector, gname);
360 		pinconf_dump_group(pctldev, s, selector, gname);
361 		seq_putc(s, '\n');
362 		selector++;
363 	}
364 
365 	return 0;
366 }
367 
368 DEFINE_SHOW_ATTRIBUTE(pinconf_pins);
369 DEFINE_SHOW_ATTRIBUTE(pinconf_groups);
370 
371 void pinconf_init_device_debugfs(struct dentry *devroot,
372 			 struct pinctrl_dev *pctldev)
373 {
374 	debugfs_create_file("pinconf-pins", S_IFREG | S_IRUGO,
375 			    devroot, pctldev, &pinconf_pins_fops);
376 	debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO,
377 			    devroot, pctldev, &pinconf_groups_fops);
378 }
379 
380 #endif
381