1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * (C) Copyright 2019 Rockchip Electronics Co., Ltd 4 */ 5 6#include <common.h> 7#include <dm.h> 8#include <dm/pinctrl.h> 9#include <regmap.h> 10#include <syscon.h> 11#include <linux/bitops.h> 12 13#include "pinctrl-rockchip.h" 14 15static int rk3036_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 16{ 17 struct rockchip_pinctrl_priv *priv = bank->priv; 18 int iomux_num = (pin / 8); 19 struct regmap *regmap; 20 int reg, ret, mask, mux_type; 21 u8 bit; 22 u32 data; 23 24 regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 25 ? priv->regmap_pmu : priv->regmap_base; 26 27 /* get basic quadrupel of mux registers and the correct reg inside */ 28 mux_type = bank->iomux[iomux_num].type; 29 reg = bank->iomux[iomux_num].offset; 30 reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask); 31 32 data = (mask << (bit + 16)); 33 data |= (mux & mask) << bit; 34 ret = regmap_write(regmap, reg, data); 35 36 return ret; 37} 38 39#define RK3036_PULL_OFFSET 0x118 40#define RK3036_PULL_PINS_PER_REG 16 41#define RK3036_PULL_BANK_STRIDE 8 42 43static void rk3036_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 44 int pin_num, struct regmap **regmap, 45 int *reg, u8 *bit) 46{ 47 struct rockchip_pinctrl_priv *priv = bank->priv; 48 49 *regmap = priv->regmap_base; 50 *reg = RK3036_PULL_OFFSET; 51 *reg += bank->bank_num * RK3036_PULL_BANK_STRIDE; 52 *reg += (pin_num / RK3036_PULL_PINS_PER_REG) * 4; 53 54 *bit = pin_num % RK3036_PULL_PINS_PER_REG; 55}; 56 57static int rk3036_set_pull(struct rockchip_pin_bank *bank, 58 int pin_num, int pull) 59{ 60 struct regmap *regmap; 61 int reg, ret; 62 u8 bit; 63 u32 data; 64 65 if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT && 66 pull != PIN_CONFIG_BIAS_DISABLE) 67 return -ENOTSUPP; 68 69 rk3036_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); 70 data = BIT(bit + 16); 71 if (pull == PIN_CONFIG_BIAS_DISABLE) 72 data |= BIT(bit); 73 ret = regmap_write(regmap, reg, data); 74 75 return ret; 76} 77 78static struct rockchip_pin_bank rk3036_pin_banks[] = { 79 PIN_BANK(0, 32, "gpio0"), 80 PIN_BANK(1, 32, "gpio1"), 81 PIN_BANK(2, 32, "gpio2"), 82}; 83 84static struct rockchip_pin_ctrl rk3036_pin_ctrl = { 85 .pin_banks = rk3036_pin_banks, 86 .nr_banks = ARRAY_SIZE(rk3036_pin_banks), 87 .grf_mux_offset = 0xa8, 88 .set_mux = rk3036_set_mux, 89 .set_pull = rk3036_set_pull, 90}; 91 92static const struct udevice_id rk3036_pinctrl_ids[] = { 93 { 94 .compatible = "rockchip,rk3036-pinctrl", 95 .data = (ulong)&rk3036_pin_ctrl 96 }, 97 {} 98}; 99 100U_BOOT_DRIVER(pinctrl_rockchip) = { 101 .name = "rk3036-pinctrl", 102 .id = UCLASS_PINCTRL, 103 .of_match = rk3036_pinctrl_ids, 104 .priv_auto = sizeof(struct rockchip_pinctrl_priv), 105 .ops = &rockchip_pinctrl_ops, 106#if CONFIG_IS_ENABLED(OF_REAL) 107 .bind = dm_scan_fdt_dev, 108#endif 109 .probe = rockchip_pinctrl_probe, 110}; 111