1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2024 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 12 #include "pinctrl-rockchip.h" 13 14 static int rv1103b_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 15 { 16 struct rockchip_pinctrl_priv *priv = bank->priv; 17 int iomux_num = (pin / 8); 18 struct regmap *regmap; 19 int reg, ret, mask; 20 u8 bit; 21 u32 data; 22 23 debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); 24 25 if (bank->bank_num == 2 && pin >= 12) 26 return 0; 27 28 regmap = priv->regmap_base; 29 reg = bank->iomux[iomux_num].offset; 30 if ((pin % 8) >= 4) 31 reg += 0x4; 32 bit = (pin % 4) * 4; 33 mask = 0xf; 34 35 if (bank->recalced_mask & BIT(pin)) 36 rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 37 data = (mask << (bit + 16)); 38 data |= (mux & mask) << bit; 39 40 debug("iomux write reg = %x data = %x\n", reg, data); 41 42 ret = regmap_write(regmap, reg, data); 43 44 return ret; 45 } 46 47 #define RV1103B_DRV_BITS_PER_PIN 8 48 #define RV1103B_DRV_PINS_PER_REG 2 49 #define RV1103B_DRV_GPIO0_A_OFFSET 0x40100 50 #define RV1103B_DRV_GPIO0_B_OFFSET 0x50110 51 #define RV1103B_DRV_GPIO1_A01_OFFSET 0x140 52 #define RV1103B_DRV_GPIO1_A67_OFFSET 0x1014C 53 #define RV1103B_DRV_GPIO2_OFFSET 0x30180 54 #define RV1103B_DRV_GPIO2_SARADC_OFFSET 0x3080C 55 56 static int rv1103b_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 57 int pin_num, struct regmap **regmap, 58 int *reg, u8 *bit) 59 { 60 struct rockchip_pinctrl_priv *priv = bank->priv; 61 int ret = 0; 62 63 *regmap = priv->regmap_base; 64 switch (bank->bank_num) { 65 case 0: 66 if (pin_num < 7) 67 *reg = RV1103B_DRV_GPIO0_A_OFFSET; 68 else if (pin_num > 7 && pin_num < 14) 69 *reg = RV1103B_DRV_GPIO0_B_OFFSET - 0x10; 70 else 71 ret = -EINVAL; 72 break; 73 74 case 1: 75 if (pin_num < 6) 76 *reg = RV1103B_DRV_GPIO1_A01_OFFSET; 77 else if (pin_num >= 6 && pin_num < 23) 78 *reg = RV1103B_DRV_GPIO1_A67_OFFSET - 0xc; 79 else if (pin_num >= 24 && pin_num < 30) 80 *reg = RV1103B_DRV_GPIO1_A67_OFFSET - 0xc; 81 else 82 ret = -EINVAL; 83 break; 84 85 case 2: 86 if (pin_num < 12) { 87 *reg = RV1103B_DRV_GPIO2_OFFSET; 88 } else if (pin_num >= 16) { 89 ret = -EINVAL; 90 } else { 91 *reg = RV1103B_DRV_GPIO2_SARADC_OFFSET; 92 *bit = 10; 93 94 return 0; 95 } 96 break; 97 98 default: 99 ret = -EINVAL; 100 break; 101 102 } 103 if (ret) { 104 dev_err(info->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num); 105 106 return ret; 107 } 108 109 *reg += ((pin_num / RV1103B_DRV_PINS_PER_REG) * 4); 110 *bit = pin_num % RV1103B_DRV_PINS_PER_REG; 111 *bit *= RV1103B_DRV_BITS_PER_PIN; 112 113 return 0; 114 } 115 116 static int rv1103b_set_drive(struct rockchip_pin_bank *bank, 117 int pin_num, int strength) 118 { 119 struct regmap *regmap; 120 int reg, ret, i; 121 u32 data; 122 u8 bit; 123 int rmask_bits = RV1103B_DRV_BITS_PER_PIN; 124 125 ret = rv1103b_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); 126 if (ret) 127 return ret; 128 129 for (i = 0, ret = 1; i < strength; i++) 130 ret = (ret << 1) | 1; 131 132 if (bank->bank_num == 2 && pin_num >= 12) { 133 rmask_bits = 2; 134 ret = strength; 135 } 136 137 /* enable the write to the equivalent lower bits */ 138 data = ((1 << rmask_bits) - 1) << (bit + 16); 139 data |= (ret << bit); 140 ret = regmap_write(regmap, reg, data); 141 142 return ret; 143 } 144 145 #define RV1103B_PULL_BITS_PER_PIN 2 146 #define RV1103B_PULL_PINS_PER_REG 8 147 #define RV1103B_PULL_GPIO0_A_OFFSET 0x40200 148 #define RV1103B_PULL_GPIO0_B_OFFSET 0x50204 149 #define RV1103B_PULL_GPIO1_A01_OFFSET 0x210 150 #define RV1103B_PULL_GPIO1_A67_OFFSET 0x10210 151 #define RV1103B_PULL_GPIO2_OFFSET 0x30220 152 #define RV1103B_PULL_GPIO2_SARADC_OFFSET 0x3080C 153 154 static int rv1103b_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 155 int pin_num, struct regmap **regmap, 156 int *reg, u8 *bit) 157 { 158 struct rockchip_pinctrl_priv *priv = bank->priv; 159 int ret = 0; 160 161 *regmap = priv->regmap_base; 162 switch (bank->bank_num) { 163 case 0: 164 if (pin_num < 7) 165 *reg = RV1103B_PULL_GPIO0_A_OFFSET; 166 else if (pin_num > 7 && pin_num < 14) 167 *reg = RV1103B_PULL_GPIO0_B_OFFSET - 0x4; 168 else 169 ret = -EINVAL; 170 break; 171 172 case 1: 173 if (pin_num < 6) 174 *reg = RV1103B_PULL_GPIO1_A01_OFFSET; 175 else if (pin_num >= 6 && pin_num < 23) 176 *reg = RV1103B_PULL_GPIO1_A67_OFFSET; 177 else if (pin_num >= 24 && pin_num < 30) 178 *reg = RV1103B_PULL_GPIO1_A67_OFFSET; 179 else 180 ret = -EINVAL; 181 break; 182 183 case 2: 184 if (pin_num < 12) { 185 *reg = RV1103B_PULL_GPIO2_OFFSET; 186 } else if (pin_num >= 16) { 187 ret = -EINVAL; 188 } else { 189 *reg = RV1103B_PULL_GPIO2_SARADC_OFFSET; 190 *bit = 13; 191 192 return 0; 193 } 194 break; 195 196 default: 197 ret = -EINVAL; 198 break; 199 } 200 201 if (ret) { 202 dev_err(info->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num); 203 204 return ret; 205 } 206 207 *reg += ((pin_num / RV1103B_PULL_PINS_PER_REG) * 4); 208 *bit = pin_num % RV1103B_PULL_PINS_PER_REG; 209 *bit *= RV1103B_PULL_BITS_PER_PIN; 210 211 return 0; 212 } 213 214 static int rv1103b_set_pull(struct rockchip_pin_bank *bank, 215 int pin_num, int pull) 216 { 217 struct regmap *regmap; 218 int reg, ret; 219 u8 bit, type; 220 u32 data; 221 222 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) 223 return -ENOTSUPP; 224 225 ret = rv1103b_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); 226 if (ret) 227 return ret; 228 type = bank->pull_type[pin_num / 8]; 229 230 if (bank->bank_num == 2 && pin_num >= 12) 231 type = 1; 232 233 ret = rockchip_translate_pull_value(type, pull); 234 if (ret < 0) { 235 debug("unsupported pull setting %d\n", pull); 236 237 return ret; 238 } 239 240 /* enable the write to the equivalent lower bits */ 241 data = ((1 << RV1103B_PULL_BITS_PER_PIN) - 1) << (bit + 16); 242 243 data |= (ret << bit); 244 ret = regmap_write(regmap, reg, data); 245 246 return ret; 247 } 248 249 #define RV1103B_SMT_BITS_PER_PIN 1 250 #define RV1103B_SMT_PINS_PER_REG 8 251 #define RV1103B_SMT_GPIO0_A_OFFSET 0x40400 252 #define RV1103B_SMT_GPIO0_B_OFFSET 0x50404 253 #define RV1103B_SMT_GPIO1_A01_OFFSET 0x410 254 #define RV1103B_SMT_GPIO1_A67_OFFSET 0x10410 255 #define RV1103B_SMT_GPIO2_OFFSET 0x30420 256 #define RV1103B_SMT_GPIO2_SARADC_OFFSET 0x3080C 257 258 static int rv1103b_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 259 int pin_num, 260 struct regmap **regmap, 261 int *reg, u8 *bit) 262 { 263 struct rockchip_pinctrl_priv *priv = bank->priv; 264 int ret = 0; 265 266 *regmap = priv->regmap_base; 267 switch (bank->bank_num) { 268 case 0: 269 if (pin_num < 7) 270 *reg = RV1103B_SMT_GPIO0_A_OFFSET; 271 else if (pin_num > 7 && pin_num < 14) 272 *reg = RV1103B_SMT_GPIO0_B_OFFSET - 0x4; 273 else 274 ret = -EINVAL; 275 break; 276 277 case 1: 278 if (pin_num < 6) 279 *reg = RV1103B_SMT_GPIO1_A01_OFFSET; 280 else if (pin_num >= 6 && pin_num < 23) 281 *reg = RV1103B_SMT_GPIO1_A67_OFFSET; 282 else if (pin_num >= 24 && pin_num < 30) 283 *reg = RV1103B_SMT_GPIO1_A67_OFFSET; 284 else 285 ret = -EINVAL; 286 break; 287 288 case 2: 289 if (pin_num < 12) { 290 *reg = RV1103B_SMT_GPIO2_OFFSET; 291 } else if (pin_num >= 16) { 292 ret = -EINVAL; 293 } else { 294 *reg = RV1103B_SMT_GPIO2_SARADC_OFFSET; 295 *bit = 8; 296 297 return 0; 298 } 299 break; 300 301 default: 302 ret = -EINVAL; 303 break; 304 305 } 306 if (ret) { 307 dev_err(info->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num); 308 309 return ret; 310 } 311 312 *reg += ((pin_num / RV1103B_SMT_PINS_PER_REG) * 4); 313 *bit = pin_num % RV1103B_SMT_PINS_PER_REG; 314 *bit *= RV1103B_SMT_BITS_PER_PIN; 315 316 return 0; 317 } 318 319 static int rv1103b_set_schmitt(struct rockchip_pin_bank *bank, 320 int pin_num, int enable) 321 { 322 struct regmap *regmap; 323 int reg, ret; 324 u32 data; 325 u8 bit; 326 327 ret = rv1103b_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); 328 if (ret) 329 return ret; 330 331 /* enable the write to the equivalent lower bits */ 332 data = ((1 << RV1103B_SMT_BITS_PER_PIN) - 1) << (bit + 16); 333 data |= (enable << bit); 334 335 if (bank->bank_num == 2 && pin_num >= 12) { 336 data = 0x3 << (bit + 16); 337 data |= ((enable ? 0x3 : 0) << bit); 338 } 339 ret = regmap_write(regmap, reg, data); 340 341 return ret; 342 } 343 344 static struct rockchip_mux_recalced_data rv1103b_mux_recalced_data[] = { 345 { 346 .num = 1, 347 .pin = 6, 348 .reg = 0x10024, 349 .bit = 8, 350 .mask = 0xf 351 }, { 352 .num = 1, 353 .pin = 7, 354 .reg = 0x10024, 355 .bit = 12, 356 .mask = 0xf 357 }, 358 }; 359 360 static struct rockchip_pin_bank rv1103b_pin_banks[] = { 361 PIN_BANK_IOMUX_FLAGS_OFFSET(0, 32, "gpio0", 362 IOMUX_WIDTH_4BIT, 363 IOMUX_WIDTH_4BIT, 364 IOMUX_WIDTH_4BIT, 365 IOMUX_WIDTH_4BIT, 366 0x40000, 0x50008, 0x50010, 0x50018), 367 PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1", 368 IOMUX_WIDTH_4BIT, 369 IOMUX_WIDTH_4BIT, 370 IOMUX_WIDTH_4BIT, 371 IOMUX_WIDTH_4BIT, 372 0x20, 0x10028, 0x10030, 0x10038), 373 PIN_BANK_IOMUX_FLAGS_OFFSET(2, 32, "gpio2", 374 IOMUX_WIDTH_4BIT, 375 IOMUX_WIDTH_4BIT, 376 IOMUX_WIDTH_4BIT, 377 IOMUX_WIDTH_4BIT, 378 0x30040, 0x30048, 0x30050, 0x30058), 379 }; 380 381 static const struct rockchip_pin_ctrl rv1103b_pin_ctrl = { 382 .pin_banks = rv1103b_pin_banks, 383 .nr_banks = ARRAY_SIZE(rv1103b_pin_banks), 384 .nr_pins = 96, 385 .iomux_recalced = rv1103b_mux_recalced_data, 386 .niomux_recalced = ARRAY_SIZE(rv1103b_mux_recalced_data), 387 .set_mux = rv1103b_set_mux, 388 .set_pull = rv1103b_set_pull, 389 .set_drive = rv1103b_set_drive, 390 .set_schmitt = rv1103b_set_schmitt, 391 }; 392 393 static const struct udevice_id rv1103b_pinctrl_ids[] = { 394 { 395 .compatible = "rockchip,rv1103b-pinctrl", 396 .data = (ulong)&rv1103b_pin_ctrl 397 }, 398 { } 399 }; 400 401 U_BOOT_DRIVER(pinctrl_rv1103b) = { 402 .name = "rockchip_rv1103b_pinctrl", 403 .id = UCLASS_PINCTRL, 404 .of_match = rv1103b_pinctrl_ids, 405 .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv), 406 .ops = &rockchip_pinctrl_ops, 407 #if !CONFIG_IS_ENABLED(OF_PLATDATA) 408 .bind = dm_scan_fdt_dev, 409 #endif 410 .probe = rockchip_pinctrl_probe, 411 }; 412