]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
pinctrl: rockchip: Add RV1103B pinctrl support
authorFabio Estevam <festevam@nabladev.com>
Sat, 7 Feb 2026 13:06:42 +0000 (10:06 -0300)
committerLinus Walleij <linusw@kernel.org>
Mon, 23 Feb 2026 09:30:49 +0000 (10:30 +0100)
Add pinctrl support for the RV1103B.

Based on the 5.10 Rockchip vendor kernel driver.

Signed-off-by: Fabio Estevam <festevam@nabladev.com>
Signed-off-by: Linus Walleij <linusw@kernel.org>
drivers/pinctrl/pinctrl-rockchip.c
drivers/pinctrl/pinctrl-rockchip.h

index d87c0b1de616dfd2cc960483a894cc3eb90f7188..d801dc64eb7f2d0759700760ded4fd589ac02b5e 100644 (file)
@@ -467,6 +467,22 @@ static const struct pinctrl_ops rockchip_pctrl_ops = {
  * Hardware access
  */
 
+static struct rockchip_mux_recalced_data rv1103b_mux_recalced_data[] = {
+       {
+               .num = 1,
+               .pin = 6,
+               .reg = 0x10024,
+               .bit = 8,
+               .mask = 0xf
+       }, {
+               .num = 1,
+               .pin = 7,
+               .reg = 0x10024,
+               .bit = 12,
+               .mask = 0xf
+       },
+};
+
 static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = {
        {
                .num = 1,
@@ -1172,6 +1188,9 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
        else
                regmap = info->regmap_base;
 
+       if (ctrl->type == RV1103B && bank->bank_num == 2 && pin >= 12)
+               return 0;
+
        if (ctrl->type == RK3506) {
                if (bank->bank_num == 1)
                        regmap = info->regmap_ioc1;
@@ -1298,6 +1317,9 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
        else
                regmap = info->regmap_base;
 
+       if (ctrl->type == RV1103B && bank->bank_num == 2 && pin >= 12)
+               return 0;
+
        if (ctrl->type == RK3506) {
                if (bank->bank_num == 1)
                        regmap = info->regmap_ioc1;
@@ -1495,6 +1517,214 @@ static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
        return 0;
 }
 
+#define RV1103B_DRV_BITS_PER_PIN               8
+#define RV1103B_DRV_PINS_PER_REG               2
+#define RV1103B_DRV_GPIO0_A_OFFSET             0x40100
+#define RV1103B_DRV_GPIO0_B_OFFSET             0x50110
+#define RV1103B_DRV_GPIO1_A01_OFFSET           0x140
+#define RV1103B_DRV_GPIO1_A67_OFFSET           0x1014C
+#define RV1103B_DRV_GPIO2_OFFSET               0x30180
+#define RV1103B_DRV_GPIO2_SARADC_OFFSET                0x3080C
+
+static int rv1103b_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+                                      int pin_num, struct regmap **regmap,
+                                      int *reg, u8 *bit)
+{
+       struct rockchip_pinctrl *info = bank->drvdata;
+       int ret = 0;
+
+       *regmap = info->regmap_base;
+       switch (bank->bank_num) {
+       case 0:
+               if (pin_num < 7)
+                       *reg = RV1103B_DRV_GPIO0_A_OFFSET;
+               else if (pin_num > 7 && pin_num < 14)
+                       *reg = RV1103B_DRV_GPIO0_B_OFFSET - 0x10;
+               else
+                       ret = -EINVAL;
+               break;
+
+       case 1:
+               if (pin_num < 6)
+                       *reg = RV1103B_DRV_GPIO1_A01_OFFSET;
+               else if (pin_num >= 6 && pin_num < 23)
+                       *reg = RV1103B_DRV_GPIO1_A67_OFFSET - 0xc;
+               else if (pin_num >= 24 && pin_num < 30)
+                       *reg = RV1103B_DRV_GPIO1_A67_OFFSET - 0xc;
+               else
+                       ret = -EINVAL;
+               break;
+
+       case 2:
+               if (pin_num < 12) {
+                       *reg = RV1103B_DRV_GPIO2_OFFSET;
+               } else if (pin_num >= 16) {
+                       ret = -EINVAL;
+               } else {
+                       *reg = RV1103B_DRV_GPIO2_SARADC_OFFSET;
+                       *bit = 10;
+
+                       return 0;
+               }
+               break;
+
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       if (ret) {
+               dev_err(info->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
+
+               return ret;
+       }
+
+       *reg += ((pin_num / RV1103B_DRV_PINS_PER_REG) * 4);
+       *bit = pin_num % RV1103B_DRV_PINS_PER_REG;
+       *bit *= RV1103B_DRV_BITS_PER_PIN;
+
+       return 0;
+}
+
+#define RV1103B_PULL_BITS_PER_PIN              2
+#define RV1103B_PULL_PINS_PER_REG              8
+#define RV1103B_PULL_GPIO0_A_OFFSET            0x40200
+#define RV1103B_PULL_GPIO0_B_OFFSET            0x50204
+#define RV1103B_PULL_GPIO1_A01_OFFSET          0x210
+#define RV1103B_PULL_GPIO1_A67_OFFSET          0x10210
+#define RV1103B_PULL_GPIO2_OFFSET              0x30220
+#define RV1103B_PULL_GPIO2_SARADC_OFFSET       0x3080C
+
+static int rv1103b_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+                                       int pin_num, struct regmap **regmap,
+                                       int *reg, u8 *bit)
+{
+       struct rockchip_pinctrl *info = bank->drvdata;
+       int ret = 0;
+
+       *regmap = info->regmap_base;
+       switch (bank->bank_num) {
+       case 0:
+               if (pin_num < 7)
+                       *reg = RV1103B_PULL_GPIO0_A_OFFSET;
+               else if (pin_num > 7 && pin_num < 14)
+                       *reg = RV1103B_PULL_GPIO0_B_OFFSET - 0x4;
+               else
+                       ret = -EINVAL;
+               break;
+
+       case 1:
+               if (pin_num < 6)
+                       *reg = RV1103B_PULL_GPIO1_A01_OFFSET;
+               else if (pin_num >= 6 && pin_num < 23)
+                       *reg = RV1103B_PULL_GPIO1_A67_OFFSET;
+               else if (pin_num >= 24 && pin_num < 30)
+                       *reg = RV1103B_PULL_GPIO1_A67_OFFSET;
+               else
+                       ret = -EINVAL;
+               break;
+
+       case 2:
+               if (pin_num < 12) {
+                       *reg = RV1103B_PULL_GPIO2_OFFSET;
+               } else if (pin_num >= 16) {
+                       ret = -EINVAL;
+               } else {
+                       *reg = RV1103B_PULL_GPIO2_SARADC_OFFSET;
+                       *bit = 13;
+
+                       return 0;
+               }
+               break;
+
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       if (ret) {
+               dev_err(info->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
+
+               return ret;
+       }
+
+       *reg += ((pin_num / RV1103B_PULL_PINS_PER_REG) * 4);
+       *bit = pin_num % RV1103B_PULL_PINS_PER_REG;
+       *bit *= RV1103B_PULL_BITS_PER_PIN;
+
+       return 0;
+}
+
+#define RV1103B_SMT_BITS_PER_PIN               1
+#define RV1103B_SMT_PINS_PER_REG               8
+#define RV1103B_SMT_GPIO0_A_OFFSET             0x40400
+#define RV1103B_SMT_GPIO0_B_OFFSET             0x50404
+#define RV1103B_SMT_GPIO1_A01_OFFSET           0x410
+#define RV1103B_SMT_GPIO1_A67_OFFSET           0x10410
+#define RV1103B_SMT_GPIO2_OFFSET               0x30420
+#define RV1103B_SMT_GPIO2_SARADC_OFFSET                0x3080C
+
+static int rv1103b_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
+                                          int pin_num,
+                                          struct regmap **regmap,
+                                          int *reg, u8 *bit)
+{
+       struct rockchip_pinctrl *info = bank->drvdata;
+       int ret = 0;
+
+       *regmap = info->regmap_base;
+       switch (bank->bank_num) {
+       case 0:
+               if (pin_num < 7)
+                       *reg = RV1103B_SMT_GPIO0_A_OFFSET;
+               else if (pin_num > 7 && pin_num < 14)
+                       *reg = RV1103B_SMT_GPIO0_B_OFFSET - 0x4;
+               else
+                       ret = -EINVAL;
+               break;
+
+       case 1:
+               if (pin_num < 6)
+                       *reg = RV1103B_SMT_GPIO1_A01_OFFSET;
+               else if (pin_num >= 6 && pin_num < 23)
+                       *reg = RV1103B_SMT_GPIO1_A67_OFFSET;
+               else if (pin_num >= 24 && pin_num < 30)
+                       *reg = RV1103B_SMT_GPIO1_A67_OFFSET;
+               else
+                       ret = -EINVAL;
+               break;
+
+       case 2:
+               if (pin_num < 12) {
+                       *reg = RV1103B_SMT_GPIO2_OFFSET;
+               } else if (pin_num >= 16) {
+                       ret = -EINVAL;
+               } else {
+                       *reg = RV1103B_SMT_GPIO2_SARADC_OFFSET;
+                       *bit = 8;
+
+                       return 0;
+               }
+               break;
+
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       if (ret) {
+               dev_err(info->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
+
+               return ret;
+       }
+
+       *reg += ((pin_num / RV1103B_SMT_PINS_PER_REG) * 4);
+       *bit = pin_num % RV1103B_SMT_PINS_PER_REG;
+       *bit *= RV1103B_SMT_BITS_PER_PIN;
+
+       return 0;
+}
+
 #define RV1108_PULL_PMU_OFFSET         0x10
 #define RV1108_PULL_OFFSET             0x110
 #define RV1108_PULL_PINS_PER_REG       8
@@ -2982,6 +3212,9 @@ static int rockchip_get_drive_perpin(struct rockchip_pin_bank *bank,
        u8 bit;
        int drv_type = bank->drv[pin_num / 8].drv_type;
 
+       if (ctrl->type == RV1103B && pin_num >= 12)
+               drv_type = DRV_TYPE_IO_LEVEL_2_BIT;
+
        ret = ctrl->drv_calc_reg(bank, pin_num, &regmap, &reg, &bit);
        if (ret)
                return ret;
@@ -3043,6 +3276,11 @@ static int rockchip_get_drive_perpin(struct rockchip_pin_bank *bank,
        if (ret)
                return ret;
 
+       if (ctrl->type == RV1103B && bank->bank_num == 2 && pin_num >= 12) {
+               data = data >> 10;
+               return data & 0x3;
+       }
+
        data >>= bit;
        data &= (1 << rmask_bits) - 1;
 
@@ -3071,7 +3309,8 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
                rmask_bits = RK3588_DRV_BITS_PER_PIN;
                ret = strength;
                goto config;
-       } else if (ctrl->type == RK3506 ||
+       } else if (ctrl->type == RV1103B ||
+                  ctrl->type == RK3506 ||
                   ctrl->type == RK3528 ||
                   ctrl->type == RK3562 ||
                   ctrl->type == RK3568) {
@@ -3182,6 +3421,12 @@ config:
                        ret = strength;
                }
        }
+
+       if (ctrl->type == RV1103B && bank->bank_num == 2 && pin_num >= 12) {
+               rmask_bits = 2;
+               ret = strength;
+       }
+
        /* enable the write to the equivalent lower bits */
        data = ((1 << rmask_bits) - 1) << (bit + 16);
        rmask = data | (data >> 16);
@@ -3236,6 +3481,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
                                ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT
                                : PIN_CONFIG_BIAS_DISABLE;
        case PX30:
+       case RV1103B:
        case RV1108:
        case RK3188:
        case RK3288:
@@ -3251,6 +3497,9 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
                pull_type = bank->pull_type[pin_num / 8];
                data >>= bit;
                data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1;
+
+               if (ctrl->type == RV1103B && bank->bank_num == 2 && pin_num >= 12)
+                       pull_type = 1;
                /*
                 * In the TRM, pull-up being 1 for everything except the GPIO0_D3-D6,
                 * where that pull up value becomes 3.
@@ -3297,6 +3546,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
                ret = regmap_write(regmap, reg, data);
                break;
        case PX30:
+       case RV1103B:
        case RV1108:
        case RV1126:
        case RK3188:
@@ -3312,6 +3562,8 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
        case RK3576:
        case RK3588:
                pull_type = bank->pull_type[pin_num / 8];
+               if (ctrl->type == RV1103B && bank->bank_num == 2 && pin_num >= 12)
+                       pull_type = 1;
                ret = -EINVAL;
                for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]);
                        i++) {
@@ -3417,6 +3669,11 @@ static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num)
        if (ret)
                return ret;
 
+       if (ctrl->type == RV1103B && bank->bank_num == 2 && pin_num >= 12) {
+               data >>= 8;
+               return data & 0x3;
+       }
+
        data >>= bit;
        switch (ctrl->type) {
        case RK3562:
@@ -3473,6 +3730,12 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
                }
        }
 
+       if (ctrl->type == RV1103B && bank->bank_num == 2 && pin_num >= 12) {
+               data = 0x3 << (bit + 16);
+               rmask = data | (data >> 16);
+               data |= ((enable ? 0x3 : 0) << bit);
+       }
+
        return regmap_update_bits(regmap, reg, rmask, data);
 }
 
@@ -3579,6 +3842,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
        case RK3066B:
                return pull ? false : true;
        case PX30:
+       case RV1103B:
        case RV1108:
        case RV1126:
        case RK3188:
@@ -4318,6 +4582,51 @@ static struct rockchip_pin_ctrl px30_pin_ctrl = {
                .schmitt_calc_reg       = px30_calc_schmitt_reg_and_bit,
 };
 
+static struct rockchip_pin_bank rv1103b_pin_banks[] = {
+       PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS(0, 32, "gpio0",
+                                   IOMUX_WIDTH_4BIT,
+                                   IOMUX_WIDTH_4BIT,
+                                   IOMUX_WIDTH_4BIT,
+                                   IOMUX_WIDTH_4BIT,
+                                   0x40000, 0x50008, 0x50010, 0x50018,
+                                   DRV_TYPE_IO_LEVEL_8_BIT,
+                                   DRV_TYPE_IO_LEVEL_8_BIT,
+                                   DRV_TYPE_IO_LEVEL_8_BIT,
+                                   DRV_TYPE_IO_LEVEL_8_BIT),
+       PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS(1, 32, "gpio1",
+                                   IOMUX_WIDTH_4BIT,
+                                   IOMUX_WIDTH_4BIT,
+                                   IOMUX_WIDTH_4BIT,
+                                   IOMUX_WIDTH_4BIT,
+                                   0x20, 0x10028, 0x10030, 0x10038,
+                                   DRV_TYPE_IO_LEVEL_8_BIT,
+                                   DRV_TYPE_IO_LEVEL_8_BIT,
+                                   DRV_TYPE_IO_LEVEL_8_BIT,
+                                   DRV_TYPE_IO_LEVEL_8_BIT),
+       PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS(2, 32, "gpio2",
+                                   IOMUX_WIDTH_4BIT,
+                                   IOMUX_WIDTH_4BIT,
+                                   IOMUX_WIDTH_4BIT,
+                                   IOMUX_WIDTH_4BIT,
+                                   0x30040, 0x30048, 0x30050, 0x30058,
+                                   DRV_TYPE_IO_LEVEL_8_BIT,
+                                   DRV_TYPE_IO_LEVEL_8_BIT,
+                                   DRV_TYPE_IO_LEVEL_8_BIT,
+                                   DRV_TYPE_IO_LEVEL_8_BIT),
+};
+
+static struct rockchip_pin_ctrl rv1103b_pin_ctrl __maybe_unused = {
+       .pin_banks              = rv1103b_pin_banks,
+       .nr_banks               = ARRAY_SIZE(rv1103b_pin_banks),
+       .label                  = "RV1103B-GPIO",
+       .type                   = RV1103B,
+       .iomux_recalced         = rv1103b_mux_recalced_data,
+       .niomux_recalced        = ARRAY_SIZE(rv1103b_mux_recalced_data),
+       .pull_calc_reg          = rv1103b_calc_pull_reg_and_bit,
+       .drv_calc_reg           = rv1103b_calc_drv_reg_and_bit,
+       .schmitt_calc_reg       = rv1103b_calc_schmitt_reg_and_bit,
+};
+
 static struct rockchip_pin_bank rv1108_pin_banks[] = {
        PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
                                             IOMUX_SOURCE_PMU,
@@ -4954,6 +5263,8 @@ static struct rockchip_pin_ctrl rk3588_pin_ctrl = {
 static const struct of_device_id rockchip_pinctrl_dt_match[] = {
        { .compatible = "rockchip,px30-pinctrl",
                .data = &px30_pin_ctrl },
+       { .compatible = "rockchip,rv1103b-pinctrl",
+               .data = &rv1103b_pin_ctrl },
        { .compatible = "rockchip,rv1108-pinctrl",
                .data = &rv1108_pin_ctrl },
        { .compatible = "rockchip,rv1126-pinctrl",
index 4f4aff42a80a9c0f7137edce8ff71c96dcb7091c..bb0e803e3b8abf6312c1fc6395f7a27320614ccd 100644 (file)
 
 enum rockchip_pinctrl_type {
        PX30,
+       RV1103B,
        RV1108,
        RV1126,
        RK2928,