Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pinctrl: tegra: Add SFIO/GPIO programming on Tegra194

Prior to Tegra186, the selection of SFIO vs. GPIO modes was done as part
of the GPIO controller's register programming. Starting with Tegra186, a
pin is configured as GPIO or SFIO with a bit in a configuration register
of the pin controller.

Signed-off-by: Thierry Reding <treding@nvidia.com>
Link: https://lore.kernel.org/r/20200319122737.3063291-10-thierry.reding@gmail.com
Tested-by: Vidya Sagar <vidyas@nvidia.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Thierry Reding and committed by
Linus Walleij
368b62f2 103afc8e

+51
+46
drivers/pinctrl/tegra/pinctrl-tegra.c
··· 275 275 return 0; 276 276 } 277 277 278 + static int tegra_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev, 279 + struct pinctrl_gpio_range *range, 280 + unsigned int offset) 281 + { 282 + struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 283 + const struct tegra_pingroup *group; 284 + u32 value; 285 + 286 + if (!pmx->soc->sfsel_in_mux) 287 + return 0; 288 + 289 + group = &pmx->soc->groups[offset]; 290 + 291 + if (group->mux_reg < 0 || group->sfsel_bit < 0) 292 + return -EINVAL; 293 + 294 + value = pmx_readl(pmx, group->mux_bank, group->mux_reg); 295 + value &= ~BIT(group->sfsel_bit); 296 + pmx_writel(pmx, value, group->mux_bank, group->mux_reg); 297 + 298 + return 0; 299 + } 300 + 301 + static void tegra_pinctrl_gpio_disable_free(struct pinctrl_dev *pctldev, 302 + struct pinctrl_gpio_range *range, 303 + unsigned int offset) 304 + { 305 + struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 306 + const struct tegra_pingroup *group; 307 + u32 value; 308 + 309 + if (!pmx->soc->sfsel_in_mux) 310 + return; 311 + 312 + group = &pmx->soc->groups[offset]; 313 + 314 + if (group->mux_reg < 0 || group->sfsel_bit < 0) 315 + return; 316 + 317 + value = pmx_readl(pmx, group->mux_bank, group->mux_reg); 318 + value |= BIT(group->sfsel_bit); 319 + pmx_writel(pmx, value, group->mux_bank, group->mux_reg); 320 + } 321 + 278 322 static const struct pinmux_ops tegra_pinmux_ops = { 279 323 .get_functions_count = tegra_pinctrl_get_funcs_count, 280 324 .get_function_name = tegra_pinctrl_get_func_name, 281 325 .get_function_groups = tegra_pinctrl_get_func_groups, 282 326 .set_mux = tegra_pinctrl_set_mux, 327 + .gpio_request_enable = tegra_pinctrl_gpio_request_enable, 328 + .gpio_disable_free = tegra_pinctrl_gpio_disable_free, 283 329 }; 284 330 285 331 static int tegra_pinconf_reg(struct tegra_pmx *pmx,
+3
drivers/pinctrl/tegra/pinctrl-tegra.h
··· 107 107 * drvup, slwr, slwf, and drvtype parameters. 108 108 * @drv_bank: Drive fields register bank. 109 109 * @hsm_bit: High Speed Mode register bit. 110 + * @sfsel_bit: GPIO/SFIO selection register bit. 110 111 * @schmitt_bit: Schmitt register bit. 111 112 * @lpmd_bit: Low Power Mode register bit. 112 113 * @drvdn_bit: Drive Down register bit. ··· 154 153 s32 ioreset_bit:6; 155 154 s32 rcv_sel_bit:6; 156 155 s32 hsm_bit:6; 156 + s32 sfsel_bit:6; 157 157 s32 schmitt_bit:6; 158 158 s32 lpmd_bit:6; 159 159 s32 drvdn_bit:6; ··· 194 192 bool hsm_in_mux; 195 193 bool schmitt_in_mux; 196 194 bool drvtype_in_mux; 195 + bool sfsel_in_mux; 197 196 }; 198 197 199 198 extern const struct dev_pm_ops tegra_pinctrl_pm;
+2
drivers/pinctrl/tegra/pinctrl-tegra194.c
··· 95 95 .tri_bit = 4, \ 96 96 .einput_bit = e_input, \ 97 97 .odrain_bit = e_od, \ 98 + .sfsel_bit = 10, \ 98 99 .schmitt_bit = schmitt_b, \ 99 100 .drvtype_bit = 13, \ 100 101 .drv_reg = -1, \ ··· 141 140 .hsm_in_mux = true, 142 141 .schmitt_in_mux = true, 143 142 .drvtype_in_mux = true, 143 + .sfsel_in_mux = true, 144 144 }; 145 145 146 146 static int tegra194_pinctrl_probe(struct platform_device *pdev)