VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   33 Branches   57 Tags
af873fcecef56 (Thomas Gleixner   2019-05-28 09:57:21 -0700   1) // SPDX-License-Identifier: GPL-2.0-only
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200   2) /*
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200   3)  * Core driver for the pin config portions of the pin control subsystem
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200   4)  *
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200   5)  * Copyright (C) 2011 ST-Ericsson SA
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200   6)  * Written on behalf of Linaro for ST-Ericsson
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200   7)  *
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200   8)  * Author: Linus Walleij <linus.walleij@linaro.org>
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200   9)  */
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  10) #define pr_fmt(fmt) "pinconfig core: " fmt
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  11) 
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  12) #include <linux/kernel.h>
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  13) #include <linux/module.h>
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  14) #include <linux/init.h>
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  15) #include <linux/device.h>
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  16) #include <linux/slab.h>
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  17) #include <linux/debugfs.h>
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  18) #include <linux/seq_file.h>
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  19) #include <linux/pinctrl/machine.h>
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  20) #include <linux/pinctrl/pinctrl.h>
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  21) #include <linux/pinctrl/pinconf.h>
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  22) #include "core.h"
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  23) #include "pinconf.h"
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  24) 
2b69425017498 (Stephen Warren    2012-02-19 23:45:46 -0700  25) int pinconf_check_ops(struct pinctrl_dev *pctldev)
2b69425017498 (Stephen Warren    2012-02-19 23:45:46 -0700  26) {
2b69425017498 (Stephen Warren    2012-02-19 23:45:46 -0700  27) 	const struct pinconf_ops *ops = pctldev->desc->confops;
2b69425017498 (Stephen Warren    2012-02-19 23:45:46 -0700  28) 
2b69425017498 (Stephen Warren    2012-02-19 23:45:46 -0700  29) 	/* We have to be able to config the pins in SOME way */
ad6e1107baa2e (John Crispin      2012-04-26 16:47:11 +0200  30) 	if (!ops->pin_config_set && !ops->pin_config_group_set) {
ad6e1107baa2e (John Crispin      2012-04-26 16:47:11 +0200  31) 		dev_err(pctldev->dev,
ad6e1107baa2e (John Crispin      2012-04-26 16:47:11 +0200  32) 			"pinconf has to be able to set a pins config\n");
2b69425017498 (Stephen Warren    2012-02-19 23:45:46 -0700  33) 		return -EINVAL;
ad6e1107baa2e (John Crispin      2012-04-26 16:47:11 +0200  34) 	}
2b69425017498 (Stephen Warren    2012-02-19 23:45:46 -0700  35) 	return 0;
2b69425017498 (Stephen Warren    2012-02-19 23:45:46 -0700  36) }
2b69425017498 (Stephen Warren    2012-02-19 23:45:46 -0700  37) 
3f713b7c223eb (Masahiro Yamada   2017-08-04 11:22:31 +0900  38) int pinconf_validate_map(const struct pinctrl_map *map, int i)
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700  39) {
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700  40) 	if (!map->data.configs.group_or_pin) {
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700  41) 		pr_err("failed to register map %s (%d): no group/pin given\n",
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700  42) 		       map->name, i);
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700  43) 		return -EINVAL;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700  44) 	}
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700  45) 
c95df2db2cb5a (Dong Aisheng      2012-05-14 19:06:36 +0800  46) 	if (!map->data.configs.num_configs ||
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700  47) 			!map->data.configs.configs) {
c95df2db2cb5a (Dong Aisheng      2012-05-14 19:06:36 +0800  48) 		pr_err("failed to register map %s (%d): no configs given\n",
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700  49) 		       map->name, i);
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700  50) 		return -EINVAL;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700  51) 	}
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700  52) 
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700  53) 	return 0;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700  54) }
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700  55) 
394349f7789fd (Linus Walleij     2011-11-24 18:27:15 +0100  56) int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  57) 			   unsigned long *config)
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  58) {
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  59) 	const struct pinconf_ops *ops = pctldev->desc->confops;
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  60) 
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  61) 	if (!ops || !ops->pin_config_get) {
ca67f10f27b6a (Masahiro Yamada   2015-07-30 17:27:44 +0900  62) 		dev_dbg(pctldev->dev,
ca67f10f27b6a (Masahiro Yamada   2015-07-30 17:27:44 +0900  63) 			"cannot get pin configuration, .pin_config_get missing in driver\n");
c420619d5177a (Alexandre Belloni 2013-12-09 11:38:29 +0100  64) 		return -ENOTSUPP;
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  65) 	}
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  66) 
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  67) 	return ops->pin_config_get(pctldev, pin, config);
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  68) }
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  69) 
43699dea1ea21 (Stephen Warren    2011-12-15 16:57:17 -0700  70) int pin_config_group_get(const char *dev_name, const char *pin_group,
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  71) 			 unsigned long *config)
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  72) {
43699dea1ea21 (Stephen Warren    2011-12-15 16:57:17 -0700  73) 	struct pinctrl_dev *pctldev;
43699dea1ea21 (Stephen Warren    2011-12-15 16:57:17 -0700  74) 	const struct pinconf_ops *ops;
57b676f9c1b7c (Stephen Warren    2012-03-02 13:05:44 -0700  75) 	int selector, ret;
57b676f9c1b7c (Stephen Warren    2012-03-02 13:05:44 -0700  76) 
9dfac4fd7f8cd (Linus Walleij     2012-02-01 18:02:47 +0100  77) 	pctldev = get_pinctrl_dev_from_devname(dev_name);
57b676f9c1b7c (Stephen Warren    2012-03-02 13:05:44 -0700  78) 	if (!pctldev) {
57b676f9c1b7c (Stephen Warren    2012-03-02 13:05:44 -0700  79) 		ret = -EINVAL;
42fed7ba44e4e (Patrice Chotard   2013-04-11 11:01:27 +0200  80) 		return ret;
57b676f9c1b7c (Stephen Warren    2012-03-02 13:05:44 -0700  81) 	}
42fed7ba44e4e (Patrice Chotard   2013-04-11 11:01:27 +0200  82) 
42fed7ba44e4e (Patrice Chotard   2013-04-11 11:01:27 +0200  83) 	mutex_lock(&pctldev->mutex);
42fed7ba44e4e (Patrice Chotard   2013-04-11 11:01:27 +0200  84) 
43699dea1ea21 (Stephen Warren    2011-12-15 16:57:17 -0700  85) 	ops = pctldev->desc->confops;
43699dea1ea21 (Stephen Warren    2011-12-15 16:57:17 -0700  86) 
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  87) 	if (!ops || !ops->pin_config_group_get) {
e4d030509f925 (Markus Elfring    2017-05-02 10:22:47 +0200  88) 		dev_dbg(pctldev->dev,
e4d030509f925 (Markus Elfring    2017-05-02 10:22:47 +0200  89) 			"cannot get configuration for pin group, missing group config get function in driver\n");
c420619d5177a (Alexandre Belloni 2013-12-09 11:38:29 +0100  90) 		ret = -ENOTSUPP;
57b676f9c1b7c (Stephen Warren    2012-03-02 13:05:44 -0700  91) 		goto unlock;
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  92) 	}
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  93) 
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  94) 	selector = pinctrl_get_group_selector(pctldev, pin_group);
57b676f9c1b7c (Stephen Warren    2012-03-02 13:05:44 -0700  95) 	if (selector < 0) {
57b676f9c1b7c (Stephen Warren    2012-03-02 13:05:44 -0700  96) 		ret = selector;
57b676f9c1b7c (Stephen Warren    2012-03-02 13:05:44 -0700  97) 		goto unlock;
57b676f9c1b7c (Stephen Warren    2012-03-02 13:05:44 -0700  98) 	}
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200  99) 
57b676f9c1b7c (Stephen Warren    2012-03-02 13:05:44 -0700 100) 	ret = ops->pin_config_group_get(pctldev, selector, config);
57b676f9c1b7c (Stephen Warren    2012-03-02 13:05:44 -0700 101) 
57b676f9c1b7c (Stephen Warren    2012-03-02 13:05:44 -0700 102) unlock:
42fed7ba44e4e (Patrice Chotard   2013-04-11 11:01:27 +0200 103) 	mutex_unlock(&pctldev->mutex);
57b676f9c1b7c (Stephen Warren    2012-03-02 13:05:44 -0700 104) 	return ret;
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 105) }
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 106) 
3f713b7c223eb (Masahiro Yamada   2017-08-04 11:22:31 +0900 107) int pinconf_map_to_setting(const struct pinctrl_map *map,
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 108) 			  struct pinctrl_setting *setting)
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 109) {
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 110) 	struct pinctrl_dev *pctldev = setting->pctldev;
70b36378d44d7 (Linus Walleij     2012-03-12 21:38:29 +0100 111) 	int pin;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 112) 
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 113) 	switch (setting->type) {
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 114) 	case PIN_MAP_TYPE_CONFIGS_PIN:
70b36378d44d7 (Linus Walleij     2012-03-12 21:38:29 +0100 115) 		pin = pin_get_from_name(pctldev,
70b36378d44d7 (Linus Walleij     2012-03-12 21:38:29 +0100 116) 					map->data.configs.group_or_pin);
70b36378d44d7 (Linus Walleij     2012-03-12 21:38:29 +0100 117) 		if (pin < 0) {
70b36378d44d7 (Linus Walleij     2012-03-12 21:38:29 +0100 118) 			dev_err(pctldev->dev, "could not map pin config for \"%s\"",
70b36378d44d7 (Linus Walleij     2012-03-12 21:38:29 +0100 119) 				map->data.configs.group_or_pin);
70b36378d44d7 (Linus Walleij     2012-03-12 21:38:29 +0100 120) 			return pin;
70b36378d44d7 (Linus Walleij     2012-03-12 21:38:29 +0100 121) 		}
70b36378d44d7 (Linus Walleij     2012-03-12 21:38:29 +0100 122) 		setting->data.configs.group_or_pin = pin;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 123) 		break;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 124) 	case PIN_MAP_TYPE_CONFIGS_GROUP:
70b36378d44d7 (Linus Walleij     2012-03-12 21:38:29 +0100 125) 		pin = pinctrl_get_group_selector(pctldev,
70b36378d44d7 (Linus Walleij     2012-03-12 21:38:29 +0100 126) 					 map->data.configs.group_or_pin);
70b36378d44d7 (Linus Walleij     2012-03-12 21:38:29 +0100 127) 		if (pin < 0) {
70b36378d44d7 (Linus Walleij     2012-03-12 21:38:29 +0100 128) 			dev_err(pctldev->dev, "could not map group config for \"%s\"",
70b36378d44d7 (Linus Walleij     2012-03-12 21:38:29 +0100 129) 				map->data.configs.group_or_pin);
70b36378d44d7 (Linus Walleij     2012-03-12 21:38:29 +0100 130) 			return pin;
70b36378d44d7 (Linus Walleij     2012-03-12 21:38:29 +0100 131) 		}
70b36378d44d7 (Linus Walleij     2012-03-12 21:38:29 +0100 132) 		setting->data.configs.group_or_pin = pin;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 133) 		break;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 134) 	default:
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 135) 		return -EINVAL;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 136) 	}
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 137) 
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 138) 	setting->data.configs.num_configs = map->data.configs.num_configs;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 139) 	setting->data.configs.configs = map->data.configs.configs;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 140) 
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 141) 	return 0;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 142) }
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 143) 
3f713b7c223eb (Masahiro Yamada   2017-08-04 11:22:31 +0900 144) void pinconf_free_setting(const struct pinctrl_setting *setting)
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 145) {
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 146) }
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 147) 
3f713b7c223eb (Masahiro Yamada   2017-08-04 11:22:31 +0900 148) int pinconf_apply_setting(const struct pinctrl_setting *setting)
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 149) {
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 150) 	struct pinctrl_dev *pctldev = setting->pctldev;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 151) 	const struct pinconf_ops *ops = pctldev->desc->confops;
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 152) 	int ret;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 153) 
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 154) 	if (!ops) {
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 155) 		dev_err(pctldev->dev, "missing confops\n");
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 156) 		return -EINVAL;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 157) 	}
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 158) 
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 159) 	switch (setting->type) {
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 160) 	case PIN_MAP_TYPE_CONFIGS_PIN:
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 161) 		if (!ops->pin_config_set) {
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 162) 			dev_err(pctldev->dev, "missing pin_config_set op\n");
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 163) 			return -EINVAL;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 164) 		}
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 165) 		ret = ops->pin_config_set(pctldev,
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 166) 				setting->data.configs.group_or_pin,
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 167) 				setting->data.configs.configs,
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 168) 				setting->data.configs.num_configs);
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 169) 		if (ret < 0) {
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 170) 			dev_err(pctldev->dev,
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 171) 				"pin_config_set op failed for pin %d\n",
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 172) 				setting->data.configs.group_or_pin);
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 173) 			return ret;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 174) 		}
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 175) 		break;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 176) 	case PIN_MAP_TYPE_CONFIGS_GROUP:
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 177) 		if (!ops->pin_config_group_set) {
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 178) 			dev_err(pctldev->dev,
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 179) 				"missing pin_config_group_set op\n");
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 180) 			return -EINVAL;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 181) 		}
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 182) 		ret = ops->pin_config_group_set(pctldev,
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 183) 				setting->data.configs.group_or_pin,
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 184) 				setting->data.configs.configs,
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 185) 				setting->data.configs.num_configs);
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 186) 		if (ret < 0) {
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 187) 			dev_err(pctldev->dev,
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 188) 				"pin_config_group_set op failed for group %d\n",
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 189) 				setting->data.configs.group_or_pin);
03b054e9696c3 (Sherman Yin       2013-08-27 11:32:12 -0700 190) 			return ret;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 191) 		}
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 192) 		break;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 193) 	default:
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 194) 		return -EINVAL;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 195) 	}
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 196) 
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 197) 	return 0;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 198) }
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 199) 
15381bc7c7f52 (Mika Westerberg   2017-01-23 15:34:33 +0300 200) int pinconf_set_config(struct pinctrl_dev *pctldev, unsigned pin,
15381bc7c7f52 (Mika Westerberg   2017-01-23 15:34:33 +0300 201) 		       unsigned long *configs, size_t nconfigs)
15381bc7c7f52 (Mika Westerberg   2017-01-23 15:34:33 +0300 202) {
15381bc7c7f52 (Mika Westerberg   2017-01-23 15:34:33 +0300 203) 	const struct pinconf_ops *ops;
15381bc7c7f52 (Mika Westerberg   2017-01-23 15:34:33 +0300 204) 
15381bc7c7f52 (Mika Westerberg   2017-01-23 15:34:33 +0300 205) 	ops = pctldev->desc->confops;
17a512486bab6 (Masahiro Yamada   2017-08-04 11:59:32 +0900 206) 	if (!ops || !ops->pin_config_set)
15381bc7c7f52 (Mika Westerberg   2017-01-23 15:34:33 +0300 207) 		return -ENOTSUPP;
15381bc7c7f52 (Mika Westerberg   2017-01-23 15:34:33 +0300 208) 
15381bc7c7f52 (Mika Westerberg   2017-01-23 15:34:33 +0300 209) 	return ops->pin_config_set(pctldev, pin, configs, nconfigs);
15381bc7c7f52 (Mika Westerberg   2017-01-23 15:34:33 +0300 210) }
15381bc7c7f52 (Mika Westerberg   2017-01-23 15:34:33 +0300 211) 
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 212) #ifdef CONFIG_DEBUG_FS
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 213) 
6de52c15132f6 (kbuild test robot 2015-07-17 21:37:09 +0800 214) static void pinconf_show_config(struct seq_file *s, struct pinctrl_dev *pctldev,
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 215) 		      unsigned long *configs, unsigned num_configs)
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 216) {
6cb4158757a86 (Stephen Warren    2012-04-13 10:49:06 -0600 217) 	const struct pinconf_ops *confops;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 218) 	int i;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 219) 
6cb4158757a86 (Stephen Warren    2012-04-13 10:49:06 -0600 220) 	if (pctldev)
6cb4158757a86 (Stephen Warren    2012-04-13 10:49:06 -0600 221) 		confops = pctldev->desc->confops;
6cb4158757a86 (Stephen Warren    2012-04-13 10:49:06 -0600 222) 	else
6cb4158757a86 (Stephen Warren    2012-04-13 10:49:06 -0600 223) 		confops = NULL;
6cb4158757a86 (Stephen Warren    2012-04-13 10:49:06 -0600 224) 
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 225) 	for (i = 0; i < num_configs; i++) {
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 226) 		seq_puts(s, "config ");
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 227) 		if (confops && confops->pin_config_config_dbg_show)
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 228) 			confops->pin_config_config_dbg_show(pctldev, s,
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 229) 							    configs[i]);
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 230) 		else
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 231) 			seq_printf(s, "%08lx", configs[i]);
47352a6375847 (Markus Elfring    2017-05-01 22:24:29 +0200 232) 		seq_putc(s, '\n');
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 233) 	}
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 234) }
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 235) 
3f713b7c223eb (Masahiro Yamada   2017-08-04 11:22:31 +0900 236) void pinconf_show_map(struct seq_file *s, const struct pinctrl_map *map)
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 237) {
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 238) 	struct pinctrl_dev *pctldev;
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 239) 
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 240) 	pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 241) 
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 242) 	switch (map->type) {
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 243) 	case PIN_MAP_TYPE_CONFIGS_PIN:
de2eae26def67 (Markus Elfring    2017-05-02 09:52:50 +0200 244) 		seq_puts(s, "pin ");
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 245) 		break;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 246) 	case PIN_MAP_TYPE_CONFIGS_GROUP:
de2eae26def67 (Markus Elfring    2017-05-02 09:52:50 +0200 247) 		seq_puts(s, "group ");
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 248) 		break;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 249) 	default:
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 250) 		break;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 251) 	}
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 252) 
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 253) 	seq_printf(s, "%s\n", map->data.configs.group_or_pin);
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 254) 
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 255) 	pinconf_show_config(s, pctldev, map->data.configs.configs,
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 256) 			    map->data.configs.num_configs);
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 257) }
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 258) 
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 259) void pinconf_show_setting(struct seq_file *s,
3f713b7c223eb (Masahiro Yamada   2017-08-04 11:22:31 +0900 260) 			  const struct pinctrl_setting *setting)
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 261) {
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 262) 	struct pinctrl_dev *pctldev = setting->pctldev;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 263) 	const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 264) 	struct pin_desc *desc;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 265) 
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 266) 	switch (setting->type) {
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 267) 	case PIN_MAP_TYPE_CONFIGS_PIN:
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 268) 		desc = pin_desc_get(setting->pctldev,
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 269) 				    setting->data.configs.group_or_pin);
cf9d994dcf00c (Masahiro Yamada   2016-05-24 14:26:26 +0900 270) 		seq_printf(s, "pin %s (%d)", desc->name,
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 271) 			   setting->data.configs.group_or_pin);
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 272) 		break;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 273) 	case PIN_MAP_TYPE_CONFIGS_GROUP:
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 274) 		seq_printf(s, "group %s (%d)",
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 275) 			   pctlops->get_group_name(pctldev,
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 276) 					setting->data.configs.group_or_pin),
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 277) 			   setting->data.configs.group_or_pin);
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 278) 		break;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 279) 	default:
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 280) 		break;
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 281) 	}
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 282) 
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 283) 	/*
3ec440e33f689 (Andy Shevchenko   2017-02-28 16:59:56 +0200 284) 	 * FIXME: We should really get the pin controller to dump the config
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 285) 	 * values, so they can be decoded to something meaningful.
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 286) 	 */
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 287) 	pinconf_show_config(s, pctldev, setting->data.configs.configs,
d96310aeddc69 (Jon Hunter        2015-07-14 11:17:59 +0100 288) 			    setting->data.configs.num_configs);
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 289) }
1e2082b520721 (Stephen Warren    2012-03-02 13:05:48 -0700 290) 
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 291) static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 292) 			     struct seq_file *s, int pin)
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 293) {
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 294) 	const struct pinconf_ops *ops = pctldev->desc->confops;
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 295) 
394349f7789fd (Linus Walleij     2011-11-24 18:27:15 +0100 296) 	/* no-op when not using generic pin config */
dd4d01f7bad88 (Soren Brinkmann   2015-01-09 07:43:46 -0800 297) 	pinconf_generic_dump_pins(pctldev, s, NULL, pin);
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 298) 	if (ops && ops->pin_config_dbg_show)
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 299) 		ops->pin_config_dbg_show(pctldev, s, pin);
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 300) }
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 301) 
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 302) static int pinconf_pins_show(struct seq_file *s, void *what)
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 303) {
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 304) 	struct pinctrl_dev *pctldev = s->private;
706e8520e8450 (Chanho Park       2012-01-03 16:47:50 +0900 305) 	unsigned i, pin;
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 306) 
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 307) 	seq_puts(s, "Pin config settings per pin\n");
2aeefe0233174 (Dong Aisheng      2012-04-16 22:07:24 +0800 308) 	seq_puts(s, "Format: pin (name): configs\n");
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 309) 
42fed7ba44e4e (Patrice Chotard   2013-04-11 11:01:27 +0200 310) 	mutex_lock(&pctldev->mutex);
57b676f9c1b7c (Stephen Warren    2012-03-02 13:05:44 -0700 311) 
706e8520e8450 (Chanho Park       2012-01-03 16:47:50 +0900 312) 	/* The pin number can be retrived from the pin controller descriptor */
546edd83abe4f (Stephen Warren    2012-01-06 13:38:31 -0700 313) 	for (i = 0; i < pctldev->desc->npins; i++) {
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 314) 		struct pin_desc *desc;
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 315) 
706e8520e8450 (Chanho Park       2012-01-03 16:47:50 +0900 316) 		pin = pctldev->desc->pins[i].number;
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 317) 		desc = pin_desc_get(pctldev, pin);
706e8520e8450 (Chanho Park       2012-01-03 16:47:50 +0900 318) 		/* Skip if we cannot search the pin */
76ce37f05ecf4 (Markus Elfring    2017-05-02 10:01:57 +0200 319) 		if (!desc)
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 320) 			continue;
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 321) 
a672eb5e277d2 (Masahiro Yamada   2016-05-25 15:37:27 +0900 322) 		seq_printf(s, "pin %d (%s): ", pin, desc->name);
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 323) 
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 324) 		pinconf_dump_pin(pctldev, s, pin);
47352a6375847 (Markus Elfring    2017-05-01 22:24:29 +0200 325) 		seq_putc(s, '\n');
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 326) 	}
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 327) 
42fed7ba44e4e (Patrice Chotard   2013-04-11 11:01:27 +0200 328) 	mutex_unlock(&pctldev->mutex);
57b676f9c1b7c (Stephen Warren    2012-03-02 13:05:44 -0700 329) 
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 330) 	return 0;
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 331) }
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 332) 
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 333) static void pinconf_dump_group(struct pinctrl_dev *pctldev,
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 334) 			       struct seq_file *s, unsigned selector,
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 335) 			       const char *gname)
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 336) {
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 337) 	const struct pinconf_ops *ops = pctldev->desc->confops;
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 338) 
394349f7789fd (Linus Walleij     2011-11-24 18:27:15 +0100 339) 	/* no-op when not using generic pin config */
dd4d01f7bad88 (Soren Brinkmann   2015-01-09 07:43:46 -0800 340) 	pinconf_generic_dump_pins(pctldev, s, gname, 0);
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 341) 	if (ops && ops->pin_config_group_dbg_show)
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 342) 		ops->pin_config_group_dbg_show(pctldev, s, selector);
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 343) }
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 344) 
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 345) static int pinconf_groups_show(struct seq_file *s, void *what)
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 346) {
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 347) 	struct pinctrl_dev *pctldev = s->private;
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 348) 	const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
d1e90e9e7467d (Viresh Kumar      2012-03-30 11:25:40 +0530 349) 	unsigned ngroups = pctlops->get_groups_count(pctldev);
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 350) 	unsigned selector = 0;
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 351) 
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 352) 	seq_puts(s, "Pin config settings per pin group\n");
2aeefe0233174 (Dong Aisheng      2012-04-16 22:07:24 +0800 353) 	seq_puts(s, "Format: group (name): configs\n");
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 354) 
d1e90e9e7467d (Viresh Kumar      2012-03-30 11:25:40 +0530 355) 	while (selector < ngroups) {
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 356) 		const char *gname = pctlops->get_group_name(pctldev, selector);
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 357) 
a672eb5e277d2 (Masahiro Yamada   2016-05-25 15:37:27 +0900 358) 		seq_printf(s, "%u (%s): ", selector, gname);
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 359) 		pinconf_dump_group(pctldev, s, selector, gname);
47352a6375847 (Markus Elfring    2017-05-01 22:24:29 +0200 360) 		seq_putc(s, '\n');
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 361) 		selector++;
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 362) 	}
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 363) 
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 364) 	return 0;
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 365) }
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 366) 
0819dc72ea70a (Yangtao Li        2018-11-30 11:36:17 -0500 367) DEFINE_SHOW_ATTRIBUTE(pinconf_pins);
0819dc72ea70a (Yangtao Li        2018-11-30 11:36:17 -0500 368) DEFINE_SHOW_ATTRIBUTE(pinconf_groups);
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 369) 
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 370) void pinconf_init_device_debugfs(struct dentry *devroot,
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 371) 			 struct pinctrl_dev *pctldev)
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 372) {
47473813bdcb8 (Drew Fustini      2021-03-01 21:30:56 -0800 373) 	debugfs_create_file("pinconf-pins", 0444,
0819dc72ea70a (Yangtao Li        2018-11-30 11:36:17 -0500 374) 			    devroot, pctldev, &pinconf_pins_fops);
47473813bdcb8 (Drew Fustini      2021-03-01 21:30:56 -0800 375) 	debugfs_create_file("pinconf-groups", 0444,
0819dc72ea70a (Yangtao Li        2018-11-30 11:36:17 -0500 376) 			    devroot, pctldev, &pinconf_groups_fops);
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 377) }
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 378) 
ae6b4d8588f4f (Linus Walleij     2011-10-19 18:14:33 +0200 379) #endif