root/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mtk_w32
  2. mtk_r32
  3. mtk_rmw
  4. mtk_hw_pin_field_lookup
  5. mtk_hw_pin_field_get
  6. mtk_hw_bits_part
  7. mtk_hw_write_cross_field
  8. mtk_hw_read_cross_field
  9. mtk_hw_set_value
  10. mtk_hw_get_value
  11. mtk_xt_find_eint_num
  12. mtk_xt_get_gpio_n
  13. mtk_xt_get_gpio_state
  14. mtk_xt_set_gpio_as_eint
  15. mtk_build_eint
  16. mtk_pinconf_bias_disable_set
  17. mtk_pinconf_bias_disable_get
  18. mtk_pinconf_bias_set
  19. mtk_pinconf_bias_get
  20. mtk_pinconf_bias_disable_set_rev1
  21. mtk_pinconf_bias_disable_get_rev1
  22. mtk_pinconf_bias_set_rev1
  23. mtk_pinconf_bias_get_rev1
  24. mtk_pinconf_drive_set
  25. mtk_pinconf_drive_get
  26. mtk_pinconf_drive_set_rev1
  27. mtk_pinconf_drive_get_rev1
  28. mtk_pinconf_adv_pull_set
  29. mtk_pinconf_adv_pull_get
  30. mtk_pinconf_adv_drive_set
  31. mtk_pinconf_adv_drive_get

   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 <linux/device.h>
  10 #include <linux/err.h>
  11 #include <linux/gpio/driver.h>
  12 #include <linux/platform_device.h>
  13 #include <linux/io.h>
  14 #include <linux/of_irq.h>
  15 
  16 #include "mtk-eint.h"
  17 #include "pinctrl-mtk-common-v2.h"
  18 
  19 /**
  20  * struct mtk_drive_desc - the structure that holds the information
  21  *                          of the driving current
  22  * @min:        the minimum current of this group
  23  * @max:        the maximum current of this group
  24  * @step:       the step current of this group
  25  * @scal:       the weight factor
  26  *
  27  * formula: output = ((input) / step - 1) * scal
  28  */
  29 struct mtk_drive_desc {
  30         u8 min;
  31         u8 max;
  32         u8 step;
  33         u8 scal;
  34 };
  35 
  36 /* The groups of drive strength */
  37 static const struct mtk_drive_desc mtk_drive[] = {
  38         [DRV_GRP0] = { 4, 16, 4, 1 },
  39         [DRV_GRP1] = { 4, 16, 4, 2 },
  40         [DRV_GRP2] = { 2, 8, 2, 1 },
  41         [DRV_GRP3] = { 2, 8, 2, 2 },
  42         [DRV_GRP4] = { 2, 16, 2, 1 },
  43 };
  44 
  45 static void mtk_w32(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 val)
  46 {
  47         writel_relaxed(val, pctl->base[i] + reg);
  48 }
  49 
  50 static u32 mtk_r32(struct mtk_pinctrl *pctl, u8 i, u32 reg)
  51 {
  52         return readl_relaxed(pctl->base[i] + reg);
  53 }
  54 
  55 void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set)
  56 {
  57         u32 val;
  58 
  59         val = mtk_r32(pctl, i, reg);
  60         val &= ~mask;
  61         val |= set;
  62         mtk_w32(pctl, i, reg, val);
  63 }
  64 
  65 static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
  66                                    const struct mtk_pin_desc *desc,
  67                                    int field, struct mtk_pin_field *pfd)
  68 {
  69         const struct mtk_pin_field_calc *c, *e;
  70         const struct mtk_pin_reg_calc *rc;
  71         u32 bits;
  72 
  73         if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
  74                 rc = &hw->soc->reg_cal[field];
  75         } else {
  76                 dev_dbg(hw->dev,
  77                         "Not support field %d for pin %d (%s)\n",
  78                         field, desc->number, desc->name);
  79                 return -ENOTSUPP;
  80         }
  81 
  82         c = rc->range;
  83         e = c + rc->nranges;
  84 
  85         while (c < e) {
  86                 if (desc->number >= c->s_pin && desc->number <= c->e_pin)
  87                         break;
  88                 c++;
  89         }
  90 
  91         if (c >= e) {
  92                 dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
  93                         field, desc->number, desc->name);
  94                 return -ENOTSUPP;
  95         }
  96 
  97         if (c->i_base > hw->nbase - 1) {
  98                 dev_err(hw->dev,
  99                         "Invalid base for field %d for pin = %d (%s)\n",
 100                         field, desc->number, desc->name);
 101                 return -EINVAL;
 102         }
 103 
 104         /* Calculated bits as the overall offset the pin is located at,
 105          * if c->fixed is held, that determines the all the pins in the
 106          * range use the same field with the s_pin.
 107          */
 108         bits = c->fixed ? c->s_bit : c->s_bit +
 109                (desc->number - c->s_pin) * (c->x_bits);
 110 
 111         /* Fill pfd from bits. For example 32-bit register applied is assumed
 112          * when c->sz_reg is equal to 32.
 113          */
 114         pfd->index = c->i_base;
 115         pfd->offset = c->s_addr + c->x_addrs * (bits / c->sz_reg);
 116         pfd->bitpos = bits % c->sz_reg;
 117         pfd->mask = (1 << c->x_bits) - 1;
 118 
 119         /* pfd->next is used for indicating that bit wrapping-around happens
 120          * which requires the manipulation for bit 0 starting in the next
 121          * register to form the complete field read/write.
 122          */
 123         pfd->next = pfd->bitpos + c->x_bits > c->sz_reg ? c->x_addrs : 0;
 124 
 125         return 0;
 126 }
 127 
 128 static int mtk_hw_pin_field_get(struct mtk_pinctrl *hw,
 129                                 const struct mtk_pin_desc *desc,
 130                                 int field, struct mtk_pin_field *pfd)
 131 {
 132         if (field < 0 || field >= PINCTRL_PIN_REG_MAX) {
 133                 dev_err(hw->dev, "Invalid Field %d\n", field);
 134                 return -EINVAL;
 135         }
 136 
 137         return mtk_hw_pin_field_lookup(hw, desc, field, pfd);
 138 }
 139 
 140 static void mtk_hw_bits_part(struct mtk_pin_field *pf, int *h, int *l)
 141 {
 142         *l = 32 - pf->bitpos;
 143         *h = get_count_order(pf->mask) - *l;
 144 }
 145 
 146 static void mtk_hw_write_cross_field(struct mtk_pinctrl *hw,
 147                                      struct mtk_pin_field *pf, int value)
 148 {
 149         int nbits_l, nbits_h;
 150 
 151         mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
 152 
 153         mtk_rmw(hw, pf->index, pf->offset, pf->mask << pf->bitpos,
 154                 (value & pf->mask) << pf->bitpos);
 155 
 156         mtk_rmw(hw, pf->index, pf->offset + pf->next, BIT(nbits_h) - 1,
 157                 (value & pf->mask) >> nbits_l);
 158 }
 159 
 160 static void mtk_hw_read_cross_field(struct mtk_pinctrl *hw,
 161                                     struct mtk_pin_field *pf, int *value)
 162 {
 163         int nbits_l, nbits_h, h, l;
 164 
 165         mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
 166 
 167         l  = (mtk_r32(hw, pf->index, pf->offset)
 168               >> pf->bitpos) & (BIT(nbits_l) - 1);
 169         h  = (mtk_r32(hw, pf->index, pf->offset + pf->next))
 170               & (BIT(nbits_h) - 1);
 171 
 172         *value = (h << nbits_l) | l;
 173 }
 174 
 175 int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
 176                      int field, int value)
 177 {
 178         struct mtk_pin_field pf;
 179         int err;
 180 
 181         err = mtk_hw_pin_field_get(hw, desc, field, &pf);
 182         if (err)
 183                 return err;
 184 
 185         if (!pf.next)
 186                 mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
 187                         (value & pf.mask) << pf.bitpos);
 188         else
 189                 mtk_hw_write_cross_field(hw, &pf, value);
 190 
 191         return 0;
 192 }
 193 
 194 int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
 195                      int field, int *value)
 196 {
 197         struct mtk_pin_field pf;
 198         int err;
 199 
 200         err = mtk_hw_pin_field_get(hw, desc, field, &pf);
 201         if (err)
 202                 return err;
 203 
 204         if (!pf.next)
 205                 *value = (mtk_r32(hw, pf.index, pf.offset)
 206                           >> pf.bitpos) & pf.mask;
 207         else
 208                 mtk_hw_read_cross_field(hw, &pf, value);
 209 
 210         return 0;
 211 }
 212 
 213 static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n)
 214 {
 215         const struct mtk_pin_desc *desc;
 216         int i = 0;
 217 
 218         desc = (const struct mtk_pin_desc *)hw->soc->pins;
 219 
 220         while (i < hw->soc->npins) {
 221                 if (desc[i].eint.eint_n == eint_n)
 222                         return desc[i].number;
 223                 i++;
 224         }
 225 
 226         return EINT_NA;
 227 }
 228 
 229 static int mtk_xt_get_gpio_n(void *data, unsigned long eint_n,
 230                              unsigned int *gpio_n,
 231                              struct gpio_chip **gpio_chip)
 232 {
 233         struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
 234         const struct mtk_pin_desc *desc;
 235 
 236         desc = (const struct mtk_pin_desc *)hw->soc->pins;
 237         *gpio_chip = &hw->chip;
 238 
 239         /* Be greedy to guess first gpio_n is equal to eint_n */
 240         if (desc[eint_n].eint.eint_n == eint_n)
 241                 *gpio_n = eint_n;
 242         else
 243                 *gpio_n = mtk_xt_find_eint_num(hw, eint_n);
 244 
 245         return *gpio_n == EINT_NA ? -EINVAL : 0;
 246 }
 247 
 248 static int mtk_xt_get_gpio_state(void *data, unsigned long eint_n)
 249 {
 250         struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
 251         const struct mtk_pin_desc *desc;
 252         struct gpio_chip *gpio_chip;
 253         unsigned int gpio_n;
 254         int value, err;
 255 
 256         err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip);
 257         if (err)
 258                 return err;
 259 
 260         desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n];
 261 
 262         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
 263         if (err)
 264                 return err;
 265 
 266         return !!value;
 267 }
 268 
 269 static int mtk_xt_set_gpio_as_eint(void *data, unsigned long eint_n)
 270 {
 271         struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
 272         const struct mtk_pin_desc *desc;
 273         struct gpio_chip *gpio_chip;
 274         unsigned int gpio_n;
 275         int err;
 276 
 277         err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip);
 278         if (err)
 279                 return err;
 280 
 281         desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n];
 282 
 283         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
 284                                desc->eint.eint_m);
 285         if (err)
 286                 return err;
 287 
 288         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_INPUT);
 289         if (err)
 290                 return err;
 291 
 292         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, MTK_ENABLE);
 293         /* SMT is supposed to be supported by every real GPIO and doesn't
 294          * support virtual GPIOs, so the extra condition err != -ENOTSUPP
 295          * is just for adding EINT support to these virtual GPIOs. It should
 296          * add an extra flag in the pin descriptor when more pins with
 297          * distinctive characteristic come out.
 298          */
 299         if (err && err != -ENOTSUPP)
 300                 return err;
 301 
 302         return 0;
 303 }
 304 
 305 static const struct mtk_eint_xt mtk_eint_xt = {
 306         .get_gpio_n = mtk_xt_get_gpio_n,
 307         .get_gpio_state = mtk_xt_get_gpio_state,
 308         .set_gpio_as_eint = mtk_xt_set_gpio_as_eint,
 309 };
 310 
 311 int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev)
 312 {
 313         struct device_node *np = pdev->dev.of_node;
 314         struct resource *res;
 315 
 316         if (!IS_ENABLED(CONFIG_EINT_MTK))
 317                 return 0;
 318 
 319         if (!of_property_read_bool(np, "interrupt-controller"))
 320                 return -ENODEV;
 321 
 322         hw->eint = devm_kzalloc(hw->dev, sizeof(*hw->eint), GFP_KERNEL);
 323         if (!hw->eint)
 324                 return -ENOMEM;
 325 
 326         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "eint");
 327         if (!res) {
 328                 dev_err(&pdev->dev, "Unable to get eint resource\n");
 329                 return -ENODEV;
 330         }
 331 
 332         hw->eint->base = devm_ioremap_resource(&pdev->dev, res);
 333         if (IS_ERR(hw->eint->base))
 334                 return PTR_ERR(hw->eint->base);
 335 
 336         hw->eint->irq = irq_of_parse_and_map(np, 0);
 337         if (!hw->eint->irq)
 338                 return -EINVAL;
 339 
 340         if (!hw->soc->eint_hw)
 341                 return -ENODEV;
 342 
 343         hw->eint->dev = &pdev->dev;
 344         hw->eint->hw = hw->soc->eint_hw;
 345         hw->eint->pctl = hw;
 346         hw->eint->gpio_xlate = &mtk_eint_xt;
 347 
 348         return mtk_eint_do_init(hw->eint);
 349 }
 350 
 351 /* Revision 0 */
 352 int mtk_pinconf_bias_disable_set(struct mtk_pinctrl *hw,
 353                                  const struct mtk_pin_desc *desc)
 354 {
 355         int err;
 356 
 357         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU,
 358                                MTK_DISABLE);
 359         if (err)
 360                 return err;
 361 
 362         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD,
 363                                MTK_DISABLE);
 364         if (err)
 365                 return err;
 366 
 367         return 0;
 368 }
 369 
 370 int mtk_pinconf_bias_disable_get(struct mtk_pinctrl *hw,
 371                                  const struct mtk_pin_desc *desc, int *res)
 372 {
 373         int v, v2;
 374         int err;
 375 
 376         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &v);
 377         if (err)
 378                 return err;
 379 
 380         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &v2);
 381         if (err)
 382                 return err;
 383 
 384         if (v == MTK_ENABLE || v2 == MTK_ENABLE)
 385                 return -EINVAL;
 386 
 387         *res = 1;
 388 
 389         return 0;
 390 }
 391 
 392 int mtk_pinconf_bias_set(struct mtk_pinctrl *hw,
 393                          const struct mtk_pin_desc *desc, bool pullup)
 394 {
 395         int err, arg;
 396 
 397         arg = pullup ? 1 : 2;
 398 
 399         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, arg & 1);
 400         if (err)
 401                 return err;
 402 
 403         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD,
 404                                !!(arg & 2));
 405         if (err)
 406                 return err;
 407 
 408         return 0;
 409 }
 410 
 411 int mtk_pinconf_bias_get(struct mtk_pinctrl *hw,
 412                          const struct mtk_pin_desc *desc, bool pullup, int *res)
 413 {
 414         int reg, err, v;
 415 
 416         reg = pullup ? PINCTRL_PIN_REG_PU : PINCTRL_PIN_REG_PD;
 417 
 418         err = mtk_hw_get_value(hw, desc, reg, &v);
 419         if (err)
 420                 return err;
 421 
 422         if (!v)
 423                 return -EINVAL;
 424 
 425         *res = 1;
 426 
 427         return 0;
 428 }
 429 
 430 /* Revision 1 */
 431 int mtk_pinconf_bias_disable_set_rev1(struct mtk_pinctrl *hw,
 432                                       const struct mtk_pin_desc *desc)
 433 {
 434         int err;
 435 
 436         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN,
 437                                MTK_DISABLE);
 438         if (err)
 439                 return err;
 440 
 441         return 0;
 442 }
 443 
 444 int mtk_pinconf_bias_disable_get_rev1(struct mtk_pinctrl *hw,
 445                                       const struct mtk_pin_desc *desc, int *res)
 446 {
 447         int v, err;
 448 
 449         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, &v);
 450         if (err)
 451                 return err;
 452 
 453         if (v == MTK_ENABLE)
 454                 return -EINVAL;
 455 
 456         *res = 1;
 457 
 458         return 0;
 459 }
 460 
 461 int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
 462                               const struct mtk_pin_desc *desc, bool pullup)
 463 {
 464         int err, arg;
 465 
 466         arg = pullup ? MTK_PULLUP : MTK_PULLDOWN;
 467 
 468         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN,
 469                                MTK_ENABLE);
 470         if (err)
 471                 return err;
 472 
 473         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, arg);
 474         if (err)
 475                 return err;
 476 
 477         return 0;
 478 }
 479 
 480 int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
 481                               const struct mtk_pin_desc *desc, bool pullup,
 482                               int *res)
 483 {
 484         int err, v;
 485 
 486         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, &v);
 487         if (err)
 488                 return err;
 489 
 490         if (v == MTK_DISABLE)
 491                 return -EINVAL;
 492 
 493         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, &v);
 494         if (err)
 495                 return err;
 496 
 497         if (pullup ^ (v == MTK_PULLUP))
 498                 return -EINVAL;
 499 
 500         *res = 1;
 501 
 502         return 0;
 503 }
 504 
 505 /* Revision 0 */
 506 int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
 507                           const struct mtk_pin_desc *desc, u32 arg)
 508 {
 509         const struct mtk_drive_desc *tb;
 510         int err = -ENOTSUPP;
 511 
 512         tb = &mtk_drive[desc->drv_n];
 513         /* 4mA when (e8, e4) = (0, 0)
 514          * 8mA when (e8, e4) = (0, 1)
 515          * 12mA when (e8, e4) = (1, 0)
 516          * 16mA when (e8, e4) = (1, 1)
 517          */
 518         if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
 519                 arg = (arg / tb->step - 1) * tb->scal;
 520                 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_E4,
 521                                        arg & 0x1);
 522                 if (err)
 523                         return err;
 524 
 525                 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_E8,
 526                                        (arg & 0x2) >> 1);
 527                 if (err)
 528                         return err;
 529         }
 530 
 531         return err;
 532 }
 533 
 534 int mtk_pinconf_drive_get(struct mtk_pinctrl *hw,
 535                           const struct mtk_pin_desc *desc, int *val)
 536 {
 537         const struct mtk_drive_desc *tb;
 538         int err, val1, val2;
 539 
 540         tb = &mtk_drive[desc->drv_n];
 541 
 542         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_E4, &val1);
 543         if (err)
 544                 return err;
 545 
 546         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_E8, &val2);
 547         if (err)
 548                 return err;
 549 
 550         /* 4mA when (e8, e4) = (0, 0); 8mA when (e8, e4) = (0, 1)
 551          * 12mA when (e8, e4) = (1, 0); 16mA when (e8, e4) = (1, 1)
 552          */
 553         *val = (((val2 << 1) + val1) / tb->scal + 1) * tb->step;
 554 
 555         return 0;
 556 }
 557 
 558 /* Revision 1 */
 559 int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
 560                                const struct mtk_pin_desc *desc, u32 arg)
 561 {
 562         const struct mtk_drive_desc *tb;
 563         int err = -ENOTSUPP;
 564 
 565         tb = &mtk_drive[desc->drv_n];
 566 
 567         if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
 568                 arg = (arg / tb->step - 1) * tb->scal;
 569 
 570                 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV,
 571                                        arg);
 572                 if (err)
 573                         return err;
 574         }
 575 
 576         return err;
 577 }
 578 
 579 int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
 580                                const struct mtk_pin_desc *desc, int *val)
 581 {
 582         const struct mtk_drive_desc *tb;
 583         int err, val1;
 584 
 585         tb = &mtk_drive[desc->drv_n];
 586 
 587         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, &val1);
 588         if (err)
 589                 return err;
 590 
 591         *val = ((val1 & 0x7) / tb->scal + 1) * tb->step;
 592 
 593         return 0;
 594 }
 595 
 596 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
 597                              const struct mtk_pin_desc *desc, bool pullup,
 598                              u32 arg)
 599 {
 600         int err;
 601 
 602         /* 10K off & 50K (75K) off, when (R0, R1) = (0, 0);
 603          * 10K off & 50K (75K) on, when (R0, R1) = (0, 1);
 604          * 10K on & 50K (75K) off, when (R0, R1) = (1, 0);
 605          * 10K on & 50K (75K) on, when (R0, R1) = (1, 1)
 606          */
 607         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, arg & 1);
 608         if (err)
 609                 return 0;
 610 
 611         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1,
 612                                !!(arg & 2));
 613         if (err)
 614                 return 0;
 615 
 616         arg = pullup ? 0 : 1;
 617 
 618         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, arg);
 619 
 620         /* If PUPD register is not supported for that pin, let's fallback to
 621          * general bias control.
 622          */
 623         if (err == -ENOTSUPP) {
 624                 if (hw->soc->bias_set) {
 625                         err = hw->soc->bias_set(hw, desc, pullup);
 626                         if (err)
 627                                 return err;
 628                 } else {
 629                         return -ENOTSUPP;
 630                 }
 631         }
 632 
 633         return err;
 634 }
 635 
 636 int mtk_pinconf_adv_pull_get(struct mtk_pinctrl *hw,
 637                              const struct mtk_pin_desc *desc, bool pullup,
 638                              u32 *val)
 639 {
 640         u32 t, t2;
 641         int err;
 642 
 643         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, &t);
 644 
 645         /* If PUPD register is not supported for that pin, let's fallback to
 646          * general bias control.
 647          */
 648         if (err == -ENOTSUPP) {
 649                 if (hw->soc->bias_get) {
 650                         err = hw->soc->bias_get(hw, desc, pullup, val);
 651                         if (err)
 652                                 return err;
 653                 } else {
 654                         return -ENOTSUPP;
 655                 }
 656         } else {
 657                 /* t == 0 supposes PULLUP for the customized PULL setup */
 658                 if (err)
 659                         return err;
 660 
 661                 if (pullup ^ !t)
 662                         return -EINVAL;
 663         }
 664 
 665         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &t);
 666         if (err)
 667                 return err;
 668 
 669         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &t2);
 670         if (err)
 671                 return err;
 672 
 673         *val = (t | t2 << 1) & 0x7;
 674 
 675         return 0;
 676 }
 677 
 678 int mtk_pinconf_adv_drive_set(struct mtk_pinctrl *hw,
 679                               const struct mtk_pin_desc *desc, u32 arg)
 680 {
 681         int err;
 682         int en = arg & 1;
 683         int e0 = !!(arg & 2);
 684         int e1 = !!(arg & 4);
 685 
 686         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_EN, en);
 687         if (err)
 688                 return err;
 689 
 690         if (!en)
 691                 return err;
 692 
 693         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_E0, e0);
 694         if (err)
 695                 return err;
 696 
 697         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_E1, e1);
 698         if (err)
 699                 return err;
 700 
 701         return err;
 702 }
 703 
 704 int mtk_pinconf_adv_drive_get(struct mtk_pinctrl *hw,
 705                               const struct mtk_pin_desc *desc, u32 *val)
 706 {
 707         u32 en, e0, e1;
 708         int err;
 709 
 710         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_EN, &en);
 711         if (err)
 712                 return err;
 713 
 714         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_E0, &e0);
 715         if (err)
 716                 return err;
 717 
 718         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_E1, &e1);
 719         if (err)
 720                 return err;
 721 
 722         *val = (en | e0 << 1 | e1 << 2) & 0x7;
 723 
 724         return 0;
 725 }

/* [<][>][^][v][top][bottom][index][help] */