Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Driver for the NVIDIA Tegra pinmux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) 2011-2012, NVIDIA CORPORATION.  All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Derived from code:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Copyright (C) 2010 Google, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Copyright (C) 2010 NVIDIA Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * Copyright (C) 2009-2011 ST-Ericsson AB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/pinctrl/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/pinctrl/pinctrl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/pinctrl/pinmux.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/pinctrl/pinconf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include "../core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include "../pinctrl-utils.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include "pinctrl-tegra.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) static inline u32 pmx_readl(struct tegra_pmx *pmx, u32 bank, u32 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	return readl(pmx->regs[bank] + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) static inline void pmx_writel(struct tegra_pmx *pmx, u32 val, u32 bank, u32 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	writel_relaxed(val, pmx->regs[bank] + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	/* make sure pinmux register write completed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	pmx_readl(pmx, bank, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) static int tegra_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	return pmx->soc->ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static const char *tegra_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 						unsigned group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	return pmx->soc->groups[group].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) static int tegra_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 					unsigned group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 					const unsigned **pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 					unsigned *num_pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	*pins = pmx->soc->groups[group].pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	*num_pins = pmx->soc->groups[group].npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) static void tegra_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 				       struct seq_file *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 				       unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	seq_printf(s, " %s", dev_name(pctldev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) static const struct cfg_param {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	const char *property;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	enum tegra_pinconf_param param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) } cfg_params[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	{"nvidia,pull",			TEGRA_PINCONF_PARAM_PULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	{"nvidia,tristate",		TEGRA_PINCONF_PARAM_TRISTATE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	{"nvidia,enable-input",		TEGRA_PINCONF_PARAM_ENABLE_INPUT},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	{"nvidia,open-drain",		TEGRA_PINCONF_PARAM_OPEN_DRAIN},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	{"nvidia,lock",			TEGRA_PINCONF_PARAM_LOCK},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	{"nvidia,io-reset",		TEGRA_PINCONF_PARAM_IORESET},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	{"nvidia,rcv-sel",		TEGRA_PINCONF_PARAM_RCV_SEL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	{"nvidia,io-hv",		TEGRA_PINCONF_PARAM_RCV_SEL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	{"nvidia,high-speed-mode",	TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	{"nvidia,schmitt",		TEGRA_PINCONF_PARAM_SCHMITT},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	{"nvidia,low-power-mode",	TEGRA_PINCONF_PARAM_LOW_POWER_MODE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	{"nvidia,pull-down-strength",	TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	{"nvidia,pull-up-strength",	TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	{"nvidia,slew-rate-falling",	TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	{"nvidia,slew-rate-rising",	TEGRA_PINCONF_PARAM_SLEW_RATE_RISING},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	{"nvidia,drive-type",		TEGRA_PINCONF_PARAM_DRIVE_TYPE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) static int tegra_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 					   struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 					   struct pinctrl_map **map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 					   unsigned *reserved_maps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 					   unsigned *num_maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	struct device *dev = pctldev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	const char *function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	unsigned long config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	unsigned long *configs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	unsigned num_configs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	unsigned reserve;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	const char *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	ret = of_property_read_string(np, "nvidia,function", &function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		/* EINVAL=missing, which is fine since it's optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		if (ret != -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 			dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 				"could not parse property nvidia,function\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		function = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		ret = of_property_read_u32(np, cfg_params[i].property, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 			config = TEGRA_PINCONF_PACK(cfg_params[i].param, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 			ret = pinctrl_utils_add_config(pctldev, &configs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 					&num_configs, config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 				goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		/* EINVAL=missing, which is fine since it's optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		} else if (ret != -EINVAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 			dev_err(dev, "could not parse property %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 				cfg_params[i].property);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	reserve = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	if (function != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		reserve++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	if (num_configs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		reserve++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	ret = of_property_count_strings(np, "nvidia,pins");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		dev_err(dev, "could not parse property nvidia,pins\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	reserve *= ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	ret = pinctrl_utils_reserve_map(pctldev, map, reserved_maps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 					num_maps, reserve);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	of_property_for_each_string(np, "nvidia,pins", prop, group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		if (function) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			ret = pinctrl_utils_add_map_mux(pctldev, map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 					reserved_maps, num_maps, group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 					function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 				goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		if (num_configs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 			ret = pinctrl_utils_add_map_configs(pctldev, map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 					reserved_maps, num_maps, group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 					configs, num_configs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 					PIN_MAP_TYPE_CONFIGS_GROUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 				goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	kfree(configs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 					struct device_node *np_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 					struct pinctrl_map **map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 					unsigned *num_maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	unsigned reserved_maps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	reserved_maps = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	*map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	*num_maps = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	for_each_child_of_node(np_config, np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		ret = tegra_pinctrl_dt_subnode_to_map(pctldev, np, map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 						      &reserved_maps, num_maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			pinctrl_utils_free_map(pctldev, *map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 				*num_maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static const struct pinctrl_ops tegra_pinctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	.get_groups_count = tegra_pinctrl_get_groups_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	.get_group_name = tegra_pinctrl_get_group_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	.get_group_pins = tegra_pinctrl_get_group_pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	.pin_dbg_show = tegra_pinctrl_pin_dbg_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	.dt_node_to_map = tegra_pinctrl_dt_node_to_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	.dt_free_map = pinctrl_utils_free_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static int tegra_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	return pmx->soc->nfunctions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static const char *tegra_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 					       unsigned function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	return pmx->soc->functions[function].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int tegra_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 					 unsigned function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 					 const char * const **groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 					 unsigned * const num_groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	*groups = pmx->soc->functions[function].groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	*num_groups = pmx->soc->functions[function].ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static int tegra_pinctrl_set_mux(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 				 unsigned function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 				 unsigned group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	const struct tegra_pingroup *g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	g = &pmx->soc->groups[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	if (WARN_ON(g->mux_reg < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	for (i = 0; i < ARRAY_SIZE(g->funcs); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		if (g->funcs[i] == function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	if (WARN_ON(i == ARRAY_SIZE(g->funcs)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	val = pmx_readl(pmx, g->mux_bank, g->mux_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	val &= ~(0x3 << g->mux_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	val |= i << g->mux_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	pmx_writel(pmx, val, g->mux_bank, g->mux_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static int tegra_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 					     struct pinctrl_gpio_range *range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 					     unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	const struct tegra_pingroup *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	if (!pmx->soc->sfsel_in_mux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	group = &pmx->soc->groups[offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	if (group->mux_reg < 0 || group->sfsel_bit < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	value = pmx_readl(pmx, group->mux_bank, group->mux_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	value &= ~BIT(group->sfsel_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	pmx_writel(pmx, value, group->mux_bank, group->mux_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static void tegra_pinctrl_gpio_disable_free(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 					    struct pinctrl_gpio_range *range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 					    unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	const struct tegra_pingroup *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	if (!pmx->soc->sfsel_in_mux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	group = &pmx->soc->groups[offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	if (group->mux_reg < 0 || group->sfsel_bit < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	value = pmx_readl(pmx, group->mux_bank, group->mux_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	value |= BIT(group->sfsel_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	pmx_writel(pmx, value, group->mux_bank, group->mux_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static const struct pinmux_ops tegra_pinmux_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	.get_functions_count = tegra_pinctrl_get_funcs_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	.get_function_name = tegra_pinctrl_get_func_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	.get_function_groups = tegra_pinctrl_get_func_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	.set_mux = tegra_pinctrl_set_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	.gpio_request_enable = tegra_pinctrl_gpio_request_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	.gpio_disable_free = tegra_pinctrl_gpio_disable_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static int tegra_pinconf_reg(struct tegra_pmx *pmx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 			     const struct tegra_pingroup *g,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 			     enum tegra_pinconf_param param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 			     bool report_err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 			     s8 *bank, s32 *reg, s8 *bit, s8 *width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	case TEGRA_PINCONF_PARAM_PULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		*bank = g->pupd_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		*reg = g->pupd_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		*bit = g->pupd_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		*width = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	case TEGRA_PINCONF_PARAM_TRISTATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		*bank = g->tri_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		*reg = g->tri_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		*bit = g->tri_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		*width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	case TEGRA_PINCONF_PARAM_ENABLE_INPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		*bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		*reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		*bit = g->einput_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		*width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	case TEGRA_PINCONF_PARAM_OPEN_DRAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		*bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		*reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		*bit = g->odrain_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		*width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	case TEGRA_PINCONF_PARAM_LOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		*bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		*reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		*bit = g->lock_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		*width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	case TEGRA_PINCONF_PARAM_IORESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		*bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		*reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		*bit = g->ioreset_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		*width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	case TEGRA_PINCONF_PARAM_RCV_SEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		*bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		*reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		*bit = g->rcv_sel_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		*width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	case TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		if (pmx->soc->hsm_in_mux) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 			*bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 			*reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 			*bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 			*reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		*bit = g->hsm_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		*width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	case TEGRA_PINCONF_PARAM_SCHMITT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		if (pmx->soc->schmitt_in_mux) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 			*bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 			*reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 			*bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 			*reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		*bit = g->schmitt_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		*width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	case TEGRA_PINCONF_PARAM_LOW_POWER_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		*bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		*reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		*bit = g->lpmd_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		*width = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	case TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		*bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		*reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		*bit = g->drvdn_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		*width = g->drvdn_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	case TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		*bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		*reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		*bit = g->drvup_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		*width = g->drvup_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	case TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		*bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		*reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		*bit = g->slwf_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		*width = g->slwf_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	case TEGRA_PINCONF_PARAM_SLEW_RATE_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		*bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		*reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		*bit = g->slwr_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		*width = g->slwr_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	case TEGRA_PINCONF_PARAM_DRIVE_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		if (pmx->soc->drvtype_in_mux) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 			*bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 			*reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 			*bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 			*reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		*bit = g->drvtype_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		*width = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		dev_err(pmx->dev, "Invalid config param %04x\n", param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	if (*reg < 0 || *bit < 0)  {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		if (report_err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 			const char *prop = "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 			int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 			for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 				if (cfg_params[i].param == param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 					prop = cfg_params[i].property;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 			dev_err(pmx->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 				"Config param %04x (%s) not supported on group %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 				param, prop, g->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static int tegra_pinconf_get(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 			     unsigned pin, unsigned long *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	dev_err(pctldev->dev, "pin_config_get op not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static int tegra_pinconf_set(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 			     unsigned pin, unsigned long *configs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 			     unsigned num_configs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	dev_err(pctldev->dev, "pin_config_set op not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static int tegra_pinconf_group_get(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 				   unsigned group, unsigned long *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(*config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	u16 arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	const struct tegra_pingroup *g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	s8 bank, bit, width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	s32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	u32 val, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	g = &pmx->soc->groups[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	ret = tegra_pinconf_reg(pmx, g, param, true, &bank, &reg, &bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 				&width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	val = pmx_readl(pmx, bank, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	mask = (1 << width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	arg = (val >> bit) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	*config = TEGRA_PINCONF_PACK(param, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 				   unsigned group, unsigned long *configs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 				   unsigned num_configs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	enum tegra_pinconf_param param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	u16 arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	const struct tegra_pingroup *g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	s8 bank, bit, width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	s32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	u32 val, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	g = &pmx->soc->groups[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	for (i = 0; i < num_configs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		param = TEGRA_PINCONF_UNPACK_PARAM(configs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		arg = TEGRA_PINCONF_UNPACK_ARG(configs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		ret = tegra_pinconf_reg(pmx, g, param, true, &bank, &reg, &bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 					&width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		val = pmx_readl(pmx, bank, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		/* LOCK can't be cleared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		if (param == TEGRA_PINCONF_PARAM_LOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 			if ((val & BIT(bit)) && !arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 				dev_err(pctldev->dev, "LOCK bit cannot be cleared\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		/* Special-case Boolean values; allow any non-zero as true */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		if (width == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 			arg = !!arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		/* Range-check user-supplied value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		mask = (1 << width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		if (arg & ~mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 			dev_err(pctldev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 				"config %lx: %x too big for %d bit register\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 				configs[i], arg, width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		/* Update register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		val &= ~(mask << bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		val |= arg << bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		pmx_writel(pmx, val, bank, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	} /* for each config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static void tegra_pinconf_dbg_show(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 				   struct seq_file *s, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static const char *strip_prefix(const char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	const char *comma = strchr(s, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	if (!comma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 		return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	return comma + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) static void tegra_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 					 struct seq_file *s, unsigned group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	const struct tegra_pingroup *g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	s8 bank, bit, width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	s32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	g = &pmx->soc->groups[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		ret = tegra_pinconf_reg(pmx, g, cfg_params[i].param, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 					&bank, &reg, &bit, &width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 		val = pmx_readl(pmx, bank, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 		val >>= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		val &= (1 << width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 		seq_printf(s, "\n\t%s=%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 			   strip_prefix(cfg_params[i].property), val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static void tegra_pinconf_config_dbg_show(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 					  struct seq_file *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 					  unsigned long config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	u16 arg = TEGRA_PINCONF_UNPACK_ARG(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	const char *pname = "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 		if (cfg_params[i].param == param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 			pname = cfg_params[i].property;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	seq_printf(s, "%s=%d", strip_prefix(pname), arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) static const struct pinconf_ops tegra_pinconf_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	.pin_config_get = tegra_pinconf_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	.pin_config_set = tegra_pinconf_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	.pin_config_group_get = tegra_pinconf_group_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	.pin_config_group_set = tegra_pinconf_group_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	.pin_config_dbg_show = tegra_pinconf_dbg_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	.pin_config_group_dbg_show = tegra_pinconf_group_dbg_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	.pin_config_config_dbg_show = tegra_pinconf_config_dbg_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) static struct pinctrl_gpio_range tegra_pinctrl_gpio_range = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	.name = "Tegra GPIOs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	.id = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	.base = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) static struct pinctrl_desc tegra_pinctrl_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	.pctlops = &tegra_pinctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	.pmxops = &tegra_pinmux_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	.confops = &tegra_pinconf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	.owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) static void tegra_pinctrl_clear_parked_bits(struct tegra_pmx *pmx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	const struct tegra_pingroup *g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	for (i = 0; i < pmx->soc->ngroups; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 		g = &pmx->soc->groups[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 		if (g->parked_bitmask > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 			unsigned int bank, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 			if (g->mux_reg != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 				bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 				reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 				bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 				reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 			val = pmx_readl(pmx, bank, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 			val &= ~g->parked_bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 			pmx_writel(pmx, val, bank, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) static size_t tegra_pinctrl_get_bank_size(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 					  unsigned int bank_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	struct platform_device *pdev = to_platform_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	res = platform_get_resource(pdev, IORESOURCE_MEM, bank_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	return resource_size(res) / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static int tegra_pinctrl_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	struct tegra_pmx *pmx = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	u32 *backup_regs = pmx->backup_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	u32 __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	size_t bank_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	unsigned int i, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	for (i = 0; i < pmx->nbanks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 		bank_size = tegra_pinctrl_get_bank_size(dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 		regs = pmx->regs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 		for (k = 0; k < bank_size; k++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 			*backup_regs++ = readl_relaxed(regs++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	return pinctrl_force_sleep(pmx->pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) static int tegra_pinctrl_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	struct tegra_pmx *pmx = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	u32 *backup_regs = pmx->backup_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	u32 __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	size_t bank_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	unsigned int i, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	for (i = 0; i < pmx->nbanks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 		bank_size = tegra_pinctrl_get_bank_size(dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 		regs = pmx->regs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		for (k = 0; k < bank_size; k++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 			writel_relaxed(*backup_regs++, regs++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	/* flush all the prior writes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	readl_relaxed(pmx->regs[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	/* wait for pinctrl register read to complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) const struct dev_pm_ops tegra_pinctrl_pm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	.suspend_noirq = &tegra_pinctrl_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	.resume_noirq = &tegra_pinctrl_resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) static bool tegra_pinctrl_gpio_node_has_range(struct tegra_pmx *pmx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	bool has_prop = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	np = of_find_compatible_node(NULL, NULL, pmx->soc->gpio_compatible);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 		return has_prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	has_prop = of_find_property(np, "gpio-ranges", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	return has_prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) int tegra_pinctrl_probe(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 			const struct tegra_pinctrl_soc_data *soc_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	struct tegra_pmx *pmx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	const char **group_pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	int fn, gn, gfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	unsigned long backup_regs_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	if (!pmx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	pmx->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	pmx->soc = soc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	 * Each mux group will appear in 4 functions' list of groups.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	 * This over-allocates slightly, since not all groups are mux groups.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 	pmx->group_pins = devm_kcalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 		soc_data->ngroups * 4, sizeof(*pmx->group_pins),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 	if (!pmx->group_pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	group_pins = pmx->group_pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	for (fn = 0; fn < soc_data->nfunctions; fn++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 		struct tegra_function *func = &soc_data->functions[fn];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 		func->groups = group_pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 		for (gn = 0; gn < soc_data->ngroups; gn++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 			const struct tegra_pingroup *g = &soc_data->groups[gn];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 			if (g->mux_reg == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 			for (gfn = 0; gfn < 4; gfn++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 				if (g->funcs[gfn] == fn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 			if (gfn == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 			BUG_ON(group_pins - pmx->group_pins >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 				soc_data->ngroups * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 			*group_pins++ = g->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 			func->ngroups++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 	tegra_pinctrl_gpio_range.npins = pmx->soc->ngpios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	tegra_pinctrl_desc.name = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	tegra_pinctrl_desc.pins = pmx->soc->pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	tegra_pinctrl_desc.npins = pmx->soc->npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 	for (i = 0; ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 		if (!res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 		backup_regs_size += resource_size(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 	pmx->nbanks = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 	pmx->regs = devm_kcalloc(&pdev->dev, pmx->nbanks, sizeof(*pmx->regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 				 GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	if (!pmx->regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 	pmx->backup_regs = devm_kzalloc(&pdev->dev, backup_regs_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 					GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 	if (!pmx->backup_regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 	for (i = 0; i < pmx->nbanks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 		pmx->regs[i] = devm_platform_ioremap_resource(pdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 		if (IS_ERR(pmx->regs[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 			return PTR_ERR(pmx->regs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	pmx->pctl = devm_pinctrl_register(&pdev->dev, &tegra_pinctrl_desc, pmx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 	if (IS_ERR(pmx->pctl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 		dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 		return PTR_ERR(pmx->pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	tegra_pinctrl_clear_parked_bits(pmx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 	if (pmx->soc->ngpios > 0 && !tegra_pinctrl_gpio_node_has_range(pmx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 		pinctrl_add_gpio_range(pmx->pctl, &tegra_pinctrl_gpio_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 	platform_set_drvdata(pdev, pmx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	dev_dbg(&pdev->dev, "Probed Tegra pinctrl driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }