1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2018 MediaTek Inc. 4 * 5 * Author: Sean Wang <sean.wang@mediatek.com> 6 * 7 */ 8 9 #include <dt-bindings/pinctrl/mt65xx.h> 10 #include <linux/device.h> 11 #include <linux/err.h> 12 #include <linux/gpio/driver.h> 13 #include <linux/platform_device.h> 14 #include <linux/io.h> 15 #include <linux/module.h> 16 #include <linux/of_irq.h> 17 18 #include "mtk-eint.h" 19 #include "pinctrl-mtk-common-v2.h" 20 21 /** 22 * struct mtk_drive_desc - the structure that holds the information 23 * of the driving current 24 * @min: the minimum current of this group 25 * @max: the maximum current of this group 26 * @step: the step current of this group 27 * @scal: the weight factor 28 * 29 * formula: output = ((input) / step - 1) * scal 30 */ 31 struct mtk_drive_desc { 32 u8 min; 33 u8 max; 34 u8 step; 35 u8 scal; 36 }; 37 38 /* The groups of drive strength */ 39 static const struct mtk_drive_desc mtk_drive[] = { 40 [DRV_GRP0] = { 4, 16, 4, 1 }, 41 [DRV_GRP1] = { 4, 16, 4, 2 }, 42 [DRV_GRP2] = { 2, 8, 2, 1 }, 43 [DRV_GRP3] = { 2, 8, 2, 2 }, 44 [DRV_GRP4] = { 2, 16, 2, 1 }, 45 }; 46 47 static void mtk_w32(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 val) 48 { 49 writel_relaxed(val, pctl->base[i] + reg); 50 } 51 52 static u32 mtk_r32(struct mtk_pinctrl *pctl, u8 i, u32 reg) 53 { 54 return readl_relaxed(pctl->base[i] + reg); 55 } 56 57 void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set) 58 { 59 u32 val; 60 unsigned long flags; 61 62 spin_lock_irqsave(&pctl->lock, flags); 63 64 val = mtk_r32(pctl, i, reg); 65 val &= ~mask; 66 val |= set; 67 mtk_w32(pctl, i, reg, val); 68 69 spin_unlock_irqrestore(&pctl->lock, flags); 70 } 71 72 static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw, 73 const struct mtk_pin_desc *desc, 74 int field, struct mtk_pin_field *pfd) 75 { 76 const struct mtk_pin_field_calc *c; 77 const struct mtk_pin_reg_calc *rc; 78 int start = 0, end, check; 79 bool found = false; 80 u32 bits; 81 82 if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) { 83 rc = &hw->soc->reg_cal[field]; 84 } else { 85 dev_dbg(hw->dev, 86 "Not support field %d for this soc\n", field); 87 return -ENOTSUPP; 88 } 89 90 end = rc->nranges - 1; 91 92 while (start <= end) { 93 check = (start + end) >> 1; 94 if (desc->number >= rc->range[check].s_pin 95 && desc->number <= rc->range[check].e_pin) { 96 found = true; 97 break; 98 } else if (start == end) 99 break; 100 else if (desc->number < rc->range[check].s_pin) 101 end = check - 1; 102 else 103 start = check + 1; 104 } 105 106 if (!found) { 107 dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n", 108 field, desc->number, desc->name); 109 return -ENOTSUPP; 110 } 111 112 c = rc->range + check; 113 114 if (c->i_base > hw->nbase - 1) { 115 dev_err(hw->dev, 116 "Invalid base for field %d for pin = %d (%s)\n", 117 field, desc->number, desc->name); 118 return -EINVAL; 119 } 120 121 /* Calculated bits as the overall offset the pin is located at, 122 * if c->fixed is held, that determines the all the pins in the 123 * range use the same field with the s_pin. 124 */ 125 bits = c->fixed ? c->s_bit : c->s_bit + 126 (desc->number - c->s_pin) * (c->x_bits); 127 128 /* Fill pfd from bits. For example 32-bit register applied is assumed 129 * when c->sz_reg is equal to 32. 130 */ 131 pfd->index = c->i_base; 132 pfd->offset = c->s_addr + c->x_addrs * (bits / c->sz_reg); 133 pfd->bitpos = bits % c->sz_reg; 134 pfd->mask = (1 << c->x_bits) - 1; 135 136 /* pfd->next is used for indicating that bit wrapping-around happens 137 * which requires the manipulation for bit 0 starting in the next 138 * register to form the complete field read/write. 139 */ 140 pfd->next = pfd->bitpos + c->x_bits > c->sz_reg ? c->x_addrs : 0; 141 142 return 0; 143 } 144 145 static int mtk_hw_pin_field_get(struct mtk_pinctrl *hw, 146 const struct mtk_pin_desc *desc, 147 int field, struct mtk_pin_field *pfd) 148 { 149 if (field < 0 || field >= PINCTRL_PIN_REG_MAX) { 150 dev_err(hw->dev, "Invalid Field %d\n", field); 151 return -EINVAL; 152 } 153 154 return mtk_hw_pin_field_lookup(hw, desc, field, pfd); 155 } 156 157 static void mtk_hw_bits_part(struct mtk_pin_field *pf, int *h, int *l) 158 { 159 *l = 32 - pf->bitpos; 160 *h = get_count_order(pf->mask) - *l; 161 } 162 163 static void mtk_hw_write_cross_field(struct mtk_pinctrl *hw, 164 struct mtk_pin_field *pf, int value) 165 { 166 int nbits_l, nbits_h; 167 168 mtk_hw_bits_part(pf, &nbits_h, &nbits_l); 169 170 mtk_rmw(hw, pf->index, pf->offset, pf->mask << pf->bitpos, 171 (value & pf->mask) << pf->bitpos); 172 173 mtk_rmw(hw, pf->index, pf->offset + pf->next, BIT(nbits_h) - 1, 174 (value & pf->mask) >> nbits_l); 175 } 176 177 static void mtk_hw_read_cross_field(struct mtk_pinctrl *hw, 178 struct mtk_pin_field *pf, int *value) 179 { 180 int nbits_l, nbits_h, h, l; 181 182 mtk_hw_bits_part(pf, &nbits_h, &nbits_l); 183 184 l = (mtk_r32(hw, pf->index, pf->offset) 185 >> pf->bitpos) & (BIT(nbits_l) - 1); 186 h = (mtk_r32(hw, pf->index, pf->offset + pf->next)) 187 & (BIT(nbits_h) - 1); 188 189 *value = (h << nbits_l) | l; 190 } 191 192 int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, 193 int field, int value) 194 { 195 struct mtk_pin_field pf; 196 int err; 197 198 err = mtk_hw_pin_field_get(hw, desc, field, &pf); 199 if (err) 200 return err; 201 202 if (value < 0 || value > pf.mask) 203 return -EINVAL; 204 205 if (!pf.next) 206 mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos, 207 (value & pf.mask) << pf.bitpos); 208 else 209 mtk_hw_write_cross_field(hw, &pf, value); 210 211 return 0; 212 } 213 EXPORT_SYMBOL_GPL(mtk_hw_set_value); 214 215 int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, 216 int field, int *value) 217 { 218 struct mtk_pin_field pf; 219 int err; 220 221 err = mtk_hw_pin_field_get(hw, desc, field, &pf); 222 if (err) 223 return err; 224 225 if (!pf.next) 226 *value = (mtk_r32(hw, pf.index, pf.offset) 227 >> pf.bitpos) & pf.mask; 228 else 229 mtk_hw_read_cross_field(hw, &pf, value); 230 231 return 0; 232 } 233 EXPORT_SYMBOL_GPL(mtk_hw_get_value); 234 235 static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n) 236 { 237 const struct mtk_pin_desc *desc; 238 int i = 0; 239 240 desc = (const struct mtk_pin_desc *)hw->soc->pins; 241 242 while (i < hw->soc->npins) { 243 if (desc[i].eint.eint_n == eint_n) 244 return desc[i].number; 245 i++; 246 } 247 248 return EINT_NA; 249 } 250 251 /* 252 * Virtual GPIO only used inside SOC and not being exported to outside SOC. 253 * Some modules use virtual GPIO as eint (e.g. pmif or usb). 254 * In MTK platform, external interrupt (EINT) and GPIO is 1-1 mapping 255 * and we can set GPIO as eint. 256 * But some modules use specific eint which doesn't have real GPIO pin. 257 * So we use virtual GPIO to map it. 258 */ 259 260 bool mtk_is_virt_gpio(struct mtk_pinctrl *hw, unsigned int gpio_n) 261 { 262 const struct mtk_pin_desc *desc; 263 bool virt_gpio = false; 264 265 desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n]; 266 267 /* if the GPIO is not supported for eint mode */ 268 if (desc->eint.eint_m == NO_EINT_SUPPORT) 269 return virt_gpio; 270 271 if (desc->funcs && !desc->funcs[desc->eint.eint_m].name) 272 virt_gpio = true; 273 274 return virt_gpio; 275 } 276 EXPORT_SYMBOL_GPL(mtk_is_virt_gpio); 277 278 static int mtk_xt_get_gpio_n(void *data, unsigned long eint_n, 279 unsigned int *gpio_n, 280 struct gpio_chip **gpio_chip) 281 { 282 struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data; 283 const struct mtk_pin_desc *desc; 284 285 desc = (const struct mtk_pin_desc *)hw->soc->pins; 286 *gpio_chip = &hw->chip; 287 288 /* 289 * Be greedy to guess first gpio_n is equal to eint_n. 290 * Only eint virtual eint number is greater than gpio number. 291 */ 292 if (hw->soc->npins > eint_n && 293 desc[eint_n].eint.eint_n == eint_n) 294 *gpio_n = eint_n; 295 else 296 *gpio_n = mtk_xt_find_eint_num(hw, eint_n); 297 298 return *gpio_n == EINT_NA ? -EINVAL : 0; 299 } 300 301 static int mtk_xt_get_gpio_state(void *data, unsigned long eint_n) 302 { 303 struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data; 304 const struct mtk_pin_desc *desc; 305 struct gpio_chip *gpio_chip; 306 unsigned int gpio_n; 307 int value, err; 308 309 err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip); 310 if (err) 311 return err; 312 313 desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n]; 314 315 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value); 316 if (err) 317 return err; 318 319 return !!value; 320 } 321 322 static int mtk_xt_set_gpio_as_eint(void *data, unsigned long eint_n) 323 { 324 struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data; 325 const struct mtk_pin_desc *desc; 326 struct gpio_chip *gpio_chip; 327 unsigned int gpio_n; 328 int err; 329 330 err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip); 331 if (err) 332 return err; 333 334 if (mtk_is_virt_gpio(hw, gpio_n)) 335 return 0; 336 337 desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n]; 338 339 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE, 340 desc->eint.eint_m); 341 if (err) 342 return err; 343 344 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_INPUT); 345 if (err) 346 return err; 347 348 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, MTK_ENABLE); 349 /* SMT is supposed to be supported by every real GPIO and doesn't 350 * support virtual GPIOs, so the extra condition err != -ENOTSUPP 351 * is just for adding EINT support to these virtual GPIOs. It should 352 * add an extra flag in the pin descriptor when more pins with 353 * distinctive characteristic come out. 354 */ 355 if (err && err != -ENOTSUPP) 356 return err; 357 358 return 0; 359 } 360 361 static const struct mtk_eint_xt mtk_eint_xt = { 362 .get_gpio_n = mtk_xt_get_gpio_n, 363 .get_gpio_state = mtk_xt_get_gpio_state, 364 .set_gpio_as_eint = mtk_xt_set_gpio_as_eint, 365 }; 366 367 int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev) 368 { 369 struct device_node *np = pdev->dev.of_node; 370 int ret; 371 372 if (!IS_ENABLED(CONFIG_EINT_MTK)) 373 return 0; 374 375 if (!of_property_read_bool(np, "interrupt-controller")) 376 return -ENODEV; 377 378 hw->eint = devm_kzalloc(hw->dev, sizeof(*hw->eint), GFP_KERNEL); 379 if (!hw->eint) 380 return -ENOMEM; 381 382 hw->eint->base = devm_platform_ioremap_resource_byname(pdev, "eint"); 383 if (IS_ERR(hw->eint->base)) { 384 ret = PTR_ERR(hw->eint->base); 385 goto err_free_eint; 386 } 387 388 hw->eint->irq = irq_of_parse_and_map(np, 0); 389 if (!hw->eint->irq) { 390 ret = -EINVAL; 391 goto err_free_eint; 392 } 393 394 if (!hw->soc->eint_hw) { 395 ret = -ENODEV; 396 goto err_free_eint; 397 } 398 399 hw->eint->dev = &pdev->dev; 400 hw->eint->hw = hw->soc->eint_hw; 401 hw->eint->pctl = hw; 402 hw->eint->gpio_xlate = &mtk_eint_xt; 403 404 return mtk_eint_do_init(hw->eint); 405 406 err_free_eint: 407 devm_kfree(hw->dev, hw->eint); 408 hw->eint = NULL; 409 return ret; 410 } 411 EXPORT_SYMBOL_GPL(mtk_build_eint); 412 413 /* Revision 0 */ 414 int mtk_pinconf_bias_disable_set(struct mtk_pinctrl *hw, 415 const struct mtk_pin_desc *desc) 416 { 417 int err; 418 419 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, 420 MTK_DISABLE); 421 if (err) 422 return err; 423 424 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, 425 MTK_DISABLE); 426 if (err) 427 return err; 428 429 return 0; 430 } 431 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_set); 432 433 int mtk_pinconf_bias_disable_get(struct mtk_pinctrl *hw, 434 const struct mtk_pin_desc *desc, int *res) 435 { 436 int v, v2; 437 int err; 438 439 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &v); 440 if (err) 441 return err; 442 443 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &v2); 444 if (err) 445 return err; 446 447 if (v == MTK_ENABLE || v2 == MTK_ENABLE) 448 return -EINVAL; 449 450 *res = 1; 451 452 return 0; 453 } 454 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_get); 455 456 int mtk_pinconf_bias_set(struct mtk_pinctrl *hw, 457 const struct mtk_pin_desc *desc, bool pullup) 458 { 459 int err, arg; 460 461 arg = pullup ? 1 : 2; 462 463 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, arg & 1); 464 if (err) 465 return err; 466 467 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, 468 !!(arg & 2)); 469 if (err) 470 return err; 471 472 return 0; 473 } 474 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set); 475 476 int mtk_pinconf_bias_get(struct mtk_pinctrl *hw, 477 const struct mtk_pin_desc *desc, bool pullup, int *res) 478 { 479 int reg, err, v; 480 481 reg = pullup ? PINCTRL_PIN_REG_PU : PINCTRL_PIN_REG_PD; 482 483 err = mtk_hw_get_value(hw, desc, reg, &v); 484 if (err) 485 return err; 486 487 if (!v) 488 return -EINVAL; 489 490 *res = 1; 491 492 return 0; 493 } 494 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get); 495 496 /* Revision 1 */ 497 int mtk_pinconf_bias_disable_set_rev1(struct mtk_pinctrl *hw, 498 const struct mtk_pin_desc *desc) 499 { 500 return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN, 501 MTK_DISABLE); 502 } 503 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_set_rev1); 504 505 int mtk_pinconf_bias_disable_get_rev1(struct mtk_pinctrl *hw, 506 const struct mtk_pin_desc *desc, int *res) 507 { 508 int v, err; 509 510 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, &v); 511 if (err) 512 return err; 513 514 if (v == MTK_ENABLE) 515 return -EINVAL; 516 517 *res = 1; 518 519 return 0; 520 } 521 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_get_rev1); 522 523 int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw, 524 const struct mtk_pin_desc *desc, bool pullup) 525 { 526 int err, arg; 527 528 arg = pullup ? MTK_PULLUP : MTK_PULLDOWN; 529 530 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN, 531 MTK_ENABLE); 532 if (err) 533 return err; 534 535 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, arg); 536 if (err) 537 return err; 538 539 return 0; 540 } 541 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_rev1); 542 543 int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw, 544 const struct mtk_pin_desc *desc, bool pullup, 545 int *res) 546 { 547 int err, v; 548 549 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, &v); 550 if (err) 551 return err; 552 553 if (v == MTK_DISABLE) 554 return -EINVAL; 555 556 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, &v); 557 if (err) 558 return err; 559 560 if (pullup ^ (v == MTK_PULLUP)) 561 return -EINVAL; 562 563 *res = 1; 564 565 return 0; 566 } 567 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_rev1); 568 569 /* Combo for the following pull register type: 570 * 1. PU + PD 571 * 2. PULLSEL + PULLEN 572 * 3. PUPD + R0 + R1 573 */ 574 static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw, 575 const struct mtk_pin_desc *desc, 576 u32 pullup, u32 arg) 577 { 578 int err, pu, pd; 579 580 if (arg == MTK_DISABLE) { 581 pu = 0; 582 pd = 0; 583 } else if ((arg == MTK_ENABLE) && pullup) { 584 pu = 1; 585 pd = 0; 586 } else if ((arg == MTK_ENABLE) && !pullup) { 587 pu = 0; 588 pd = 1; 589 } else { 590 err = -EINVAL; 591 goto out; 592 } 593 594 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu); 595 if (err) 596 goto out; 597 598 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd); 599 600 out: 601 return err; 602 } 603 604 static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw, 605 const struct mtk_pin_desc *desc, 606 u32 pullup, u32 arg) 607 { 608 int err, enable; 609 610 if (arg == MTK_DISABLE) 611 enable = 0; 612 else if (arg == MTK_ENABLE) 613 enable = 1; 614 else { 615 err = -EINVAL; 616 goto out; 617 } 618 619 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable); 620 if (err) 621 goto out; 622 623 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup); 624 625 out: 626 return err; 627 } 628 629 static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw, 630 const struct mtk_pin_desc *desc, 631 u32 pullup, u32 arg) 632 { 633 int err, r0, r1; 634 635 if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) { 636 pullup = 0; 637 r0 = 0; 638 r1 = 0; 639 } else if (arg == MTK_PUPD_SET_R1R0_01) { 640 r0 = 1; 641 r1 = 0; 642 } else if (arg == MTK_PUPD_SET_R1R0_10) { 643 r0 = 0; 644 r1 = 1; 645 } else if (arg == MTK_PUPD_SET_R1R0_11) { 646 r0 = 1; 647 r1 = 1; 648 } else { 649 err = -EINVAL; 650 goto out; 651 } 652 653 /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */ 654 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, !pullup); 655 if (err) 656 goto out; 657 658 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, r0); 659 if (err) 660 goto out; 661 662 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1, r1); 663 664 out: 665 return err; 666 } 667 668 static int mtk_hw_pin_rsel_lookup(struct mtk_pinctrl *hw, 669 const struct mtk_pin_desc *desc, 670 u32 pullup, u32 arg, u32 *rsel_val) 671 { 672 const struct mtk_pin_rsel *rsel; 673 int check; 674 bool found = false; 675 676 rsel = hw->soc->pin_rsel; 677 678 for (check = 0; check <= hw->soc->npin_rsel - 1; check++) { 679 if (desc->number >= rsel[check].s_pin && 680 desc->number <= rsel[check].e_pin) { 681 if (pullup) { 682 if (rsel[check].up_rsel == arg) { 683 found = true; 684 *rsel_val = rsel[check].rsel_index; 685 break; 686 } 687 } else { 688 if (rsel[check].down_rsel == arg) { 689 found = true; 690 *rsel_val = rsel[check].rsel_index; 691 break; 692 } 693 } 694 } 695 } 696 697 if (!found) { 698 dev_err(hw->dev, "Not support rsel value %d Ohm for pin = %d (%s)\n", 699 arg, desc->number, desc->name); 700 return -ENOTSUPP; 701 } 702 703 return 0; 704 } 705 706 static int mtk_pinconf_bias_set_rsel(struct mtk_pinctrl *hw, 707 const struct mtk_pin_desc *desc, 708 u32 pullup, u32 arg) 709 { 710 int err, rsel_val; 711 712 if (hw->rsel_si_unit) { 713 /* find pin rsel_index from pin_rsel array*/ 714 err = mtk_hw_pin_rsel_lookup(hw, desc, pullup, arg, &rsel_val); 715 if (err) 716 goto out; 717 } else { 718 if (arg < MTK_PULL_SET_RSEL_000 || 719 arg > MTK_PULL_SET_RSEL_111) { 720 err = -EINVAL; 721 goto out; 722 } 723 724 rsel_val = arg - MTK_PULL_SET_RSEL_000; 725 } 726 727 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_RSEL, rsel_val); 728 if (err) 729 goto out; 730 731 err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, MTK_ENABLE); 732 733 out: 734 return err; 735 } 736 737 int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw, 738 const struct mtk_pin_desc *desc, 739 u32 pullup, u32 arg) 740 { 741 int err = -ENOTSUPP; 742 u32 try_all_type; 743 744 if (hw->soc->pull_type) 745 try_all_type = hw->soc->pull_type[desc->number]; 746 else 747 try_all_type = MTK_PULL_TYPE_MASK; 748 749 if (try_all_type & MTK_PULL_RSEL_TYPE) { 750 err = mtk_pinconf_bias_set_rsel(hw, desc, pullup, arg); 751 if (!err) 752 return err; 753 } 754 755 if (try_all_type & MTK_PULL_PU_PD_TYPE) { 756 err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg); 757 if (!err) 758 return err; 759 } 760 761 if (try_all_type & MTK_PULL_PULLSEL_TYPE) { 762 err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, 763 pullup, arg); 764 if (!err) 765 return err; 766 } 767 768 if (try_all_type & MTK_PULL_PUPD_R1R0_TYPE) 769 err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg); 770 771 if (err) 772 dev_err(hw->dev, "Invalid pull argument\n"); 773 774 return err; 775 } 776 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_combo); 777 778 static int mtk_rsel_get_si_unit(struct mtk_pinctrl *hw, 779 const struct mtk_pin_desc *desc, 780 u32 pullup, u32 rsel_val, u32 *si_unit) 781 { 782 const struct mtk_pin_rsel *rsel; 783 int check; 784 785 rsel = hw->soc->pin_rsel; 786 787 for (check = 0; check <= hw->soc->npin_rsel - 1; check++) { 788 if (desc->number >= rsel[check].s_pin && 789 desc->number <= rsel[check].e_pin) { 790 if (rsel_val == rsel[check].rsel_index) { 791 if (pullup) 792 *si_unit = rsel[check].up_rsel; 793 else 794 *si_unit = rsel[check].down_rsel; 795 break; 796 } 797 } 798 } 799 800 return 0; 801 } 802 803 static int mtk_pinconf_bias_get_rsel(struct mtk_pinctrl *hw, 804 const struct mtk_pin_desc *desc, 805 u32 *pullup, u32 *enable) 806 { 807 int pu, pd, rsel, err; 808 809 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_RSEL, &rsel); 810 if (err) 811 goto out; 812 813 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu); 814 if (err) 815 goto out; 816 817 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd); 818 if (err) 819 goto out; 820 821 if (pu == 0 && pd == 0) { 822 *pullup = 0; 823 *enable = MTK_DISABLE; 824 } else if (pu == 1 && pd == 0) { 825 *pullup = 1; 826 if (hw->rsel_si_unit) 827 mtk_rsel_get_si_unit(hw, desc, *pullup, rsel, enable); 828 else 829 *enable = rsel + MTK_PULL_SET_RSEL_000; 830 } else if (pu == 0 && pd == 1) { 831 *pullup = 0; 832 if (hw->rsel_si_unit) 833 mtk_rsel_get_si_unit(hw, desc, *pullup, rsel, enable); 834 else 835 *enable = rsel + MTK_PULL_SET_RSEL_000; 836 } else { 837 err = -EINVAL; 838 goto out; 839 } 840 841 out: 842 return err; 843 } 844 845 static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw, 846 const struct mtk_pin_desc *desc, 847 u32 *pullup, u32 *enable) 848 { 849 int err, pu, pd; 850 851 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu); 852 if (err) 853 goto out; 854 855 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd); 856 if (err) 857 goto out; 858 859 if (pu == 0 && pd == 0) { 860 *pullup = 0; 861 *enable = MTK_DISABLE; 862 } else if (pu == 1 && pd == 0) { 863 *pullup = 1; 864 *enable = MTK_ENABLE; 865 } else if (pu == 0 && pd == 1) { 866 *pullup = 0; 867 *enable = MTK_ENABLE; 868 } else 869 err = -EINVAL; 870 871 out: 872 return err; 873 } 874 875 static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw, 876 const struct mtk_pin_desc *desc, 877 u32 *pullup, u32 *enable) 878 { 879 int err; 880 881 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup); 882 if (err) 883 goto out; 884 885 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable); 886 887 out: 888 return err; 889 } 890 891 static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw, 892 const struct mtk_pin_desc *desc, 893 u32 *pullup, u32 *enable) 894 { 895 int err, r0, r1; 896 897 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, pullup); 898 if (err) 899 goto out; 900 /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */ 901 *pullup = !(*pullup); 902 903 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &r0); 904 if (err) 905 goto out; 906 907 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &r1); 908 if (err) 909 goto out; 910 911 if ((r1 == 0) && (r0 == 0)) 912 *enable = MTK_PUPD_SET_R1R0_00; 913 else if ((r1 == 0) && (r0 == 1)) 914 *enable = MTK_PUPD_SET_R1R0_01; 915 else if ((r1 == 1) && (r0 == 0)) 916 *enable = MTK_PUPD_SET_R1R0_10; 917 else if ((r1 == 1) && (r0 == 1)) 918 *enable = MTK_PUPD_SET_R1R0_11; 919 else 920 err = -EINVAL; 921 922 out: 923 return err; 924 } 925 926 int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw, 927 const struct mtk_pin_desc *desc, 928 u32 *pullup, u32 *enable) 929 { 930 int err = -ENOTSUPP; 931 u32 try_all_type; 932 933 if (hw->soc->pull_type) 934 try_all_type = hw->soc->pull_type[desc->number]; 935 else 936 try_all_type = MTK_PULL_TYPE_MASK; 937 938 if (try_all_type & MTK_PULL_RSEL_TYPE) { 939 err = mtk_pinconf_bias_get_rsel(hw, desc, pullup, enable); 940 if (!err) 941 return err; 942 } 943 944 if (try_all_type & MTK_PULL_PU_PD_TYPE) { 945 err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable); 946 if (!err) 947 return err; 948 } 949 950 if (try_all_type & MTK_PULL_PULLSEL_TYPE) { 951 err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, 952 pullup, enable); 953 if (!err) 954 return err; 955 } 956 957 if (try_all_type & MTK_PULL_PUPD_R1R0_TYPE) 958 err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable); 959 960 return err; 961 } 962 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_combo); 963 964 /* Revision 0 */ 965 int mtk_pinconf_drive_set(struct mtk_pinctrl *hw, 966 const struct mtk_pin_desc *desc, u32 arg) 967 { 968 const struct mtk_drive_desc *tb; 969 int err = -ENOTSUPP; 970 971 tb = &mtk_drive[desc->drv_n]; 972 /* 4mA when (e8, e4) = (0, 0) 973 * 8mA when (e8, e4) = (0, 1) 974 * 12mA when (e8, e4) = (1, 0) 975 * 16mA when (e8, e4) = (1, 1) 976 */ 977 if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) { 978 arg = (arg / tb->step - 1) * tb->scal; 979 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_E4, 980 arg & 0x1); 981 if (err) 982 return err; 983 984 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_E8, 985 (arg & 0x2) >> 1); 986 if (err) 987 return err; 988 } 989 990 return err; 991 } 992 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set); 993 994 int mtk_pinconf_drive_get(struct mtk_pinctrl *hw, 995 const struct mtk_pin_desc *desc, int *val) 996 { 997 const struct mtk_drive_desc *tb; 998 int err, val1, val2; 999 1000 tb = &mtk_drive[desc->drv_n]; 1001 1002 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_E4, &val1); 1003 if (err) 1004 return err; 1005 1006 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_E8, &val2); 1007 if (err) 1008 return err; 1009 1010 /* 4mA when (e8, e4) = (0, 0); 8mA when (e8, e4) = (0, 1) 1011 * 12mA when (e8, e4) = (1, 0); 16mA when (e8, e4) = (1, 1) 1012 */ 1013 *val = (((val2 << 1) + val1) / tb->scal + 1) * tb->step; 1014 1015 return 0; 1016 } 1017 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get); 1018 1019 /* Revision 1 */ 1020 int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw, 1021 const struct mtk_pin_desc *desc, u32 arg) 1022 { 1023 const struct mtk_drive_desc *tb; 1024 int err = -ENOTSUPP; 1025 1026 tb = &mtk_drive[desc->drv_n]; 1027 1028 if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) { 1029 arg = (arg / tb->step - 1) * tb->scal; 1030 1031 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, 1032 arg); 1033 if (err) 1034 return err; 1035 } 1036 1037 return err; 1038 } 1039 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set_rev1); 1040 1041 int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw, 1042 const struct mtk_pin_desc *desc, int *val) 1043 { 1044 const struct mtk_drive_desc *tb; 1045 int err, val1; 1046 1047 tb = &mtk_drive[desc->drv_n]; 1048 1049 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, &val1); 1050 if (err) 1051 return err; 1052 1053 *val = ((val1 & 0x7) / tb->scal + 1) * tb->step; 1054 1055 return 0; 1056 } 1057 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get_rev1); 1058 1059 int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw, 1060 const struct mtk_pin_desc *desc, u32 arg) 1061 { 1062 return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg); 1063 } 1064 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set_raw); 1065 1066 int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw, 1067 const struct mtk_pin_desc *desc, int *val) 1068 { 1069 return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val); 1070 } 1071 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get_raw); 1072 1073 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw, 1074 const struct mtk_pin_desc *desc, bool pullup, 1075 u32 arg) 1076 { 1077 int err; 1078 1079 /* 10K off & 50K (75K) off, when (R0, R1) = (0, 0); 1080 * 10K off & 50K (75K) on, when (R0, R1) = (0, 1); 1081 * 10K on & 50K (75K) off, when (R0, R1) = (1, 0); 1082 * 10K on & 50K (75K) on, when (R0, R1) = (1, 1) 1083 */ 1084 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, arg & 1); 1085 if (err) 1086 return 0; 1087 1088 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1, 1089 !!(arg & 2)); 1090 if (err) 1091 return 0; 1092 1093 arg = pullup ? 0 : 1; 1094 1095 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, arg); 1096 1097 /* If PUPD register is not supported for that pin, let's fallback to 1098 * general bias control. 1099 */ 1100 if (err == -ENOTSUPP) { 1101 if (hw->soc->bias_set) { 1102 err = hw->soc->bias_set(hw, desc, pullup); 1103 if (err) 1104 return err; 1105 } else { 1106 err = mtk_pinconf_bias_set_rev1(hw, desc, pullup); 1107 if (err) 1108 err = mtk_pinconf_bias_set(hw, desc, pullup); 1109 } 1110 } 1111 1112 return err; 1113 } 1114 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_pull_set); 1115 1116 int mtk_pinconf_adv_pull_get(struct mtk_pinctrl *hw, 1117 const struct mtk_pin_desc *desc, bool pullup, 1118 u32 *val) 1119 { 1120 u32 t, t2; 1121 int err; 1122 1123 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, &t); 1124 1125 /* If PUPD register is not supported for that pin, let's fallback to 1126 * general bias control. 1127 */ 1128 if (err == -ENOTSUPP) { 1129 if (hw->soc->bias_get) { 1130 err = hw->soc->bias_get(hw, desc, pullup, val); 1131 if (err) 1132 return err; 1133 } else { 1134 return -ENOTSUPP; 1135 } 1136 } else { 1137 /* t == 0 supposes PULLUP for the customized PULL setup */ 1138 if (err) 1139 return err; 1140 1141 if (pullup ^ !t) 1142 return -EINVAL; 1143 } 1144 1145 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &t); 1146 if (err) 1147 return err; 1148 1149 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &t2); 1150 if (err) 1151 return err; 1152 1153 *val = (t | t2 << 1) & 0x7; 1154 1155 return 0; 1156 } 1157 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_pull_get); 1158 1159 int mtk_pinconf_adv_drive_set(struct mtk_pinctrl *hw, 1160 const struct mtk_pin_desc *desc, u32 arg) 1161 { 1162 int err; 1163 int en = arg & 1; 1164 int e0 = !!(arg & 2); 1165 int e1 = !!(arg & 4); 1166 1167 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_EN, en); 1168 if (err) 1169 return err; 1170 1171 if (!en) 1172 return err; 1173 1174 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_E0, e0); 1175 if (err) 1176 return err; 1177 1178 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_E1, e1); 1179 if (err) 1180 return err; 1181 1182 return err; 1183 } 1184 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_set); 1185 1186 int mtk_pinconf_adv_drive_get(struct mtk_pinctrl *hw, 1187 const struct mtk_pin_desc *desc, u32 *val) 1188 { 1189 u32 en, e0, e1; 1190 int err; 1191 1192 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_EN, &en); 1193 if (err) 1194 return err; 1195 1196 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_E0, &e0); 1197 if (err) 1198 return err; 1199 1200 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_E1, &e1); 1201 if (err) 1202 return err; 1203 1204 *val = (en | e0 << 1 | e1 << 2) & 0x7; 1205 1206 return 0; 1207 } 1208 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_get); 1209 1210 int mtk_pinconf_adv_drive_set_raw(struct mtk_pinctrl *hw, 1211 const struct mtk_pin_desc *desc, u32 arg) 1212 { 1213 return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_ADV, arg); 1214 } 1215 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_set_raw); 1216 1217 int mtk_pinconf_adv_drive_get_raw(struct mtk_pinctrl *hw, 1218 const struct mtk_pin_desc *desc, u32 *val) 1219 { 1220 return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_ADV, val); 1221 } 1222 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_get_raw); 1223 1224 MODULE_LICENSE("GPL v2"); 1225 MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); 1226 MODULE_DESCRIPTION("Pin configuration library module for mediatek SoCs"); 1227