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