linux/drivers/usb/typec/typec_wcove.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/**
   3 * typec_wcove.c - WhiskeyCove PMIC USB Type-C PHY driver
   4 *
   5 * Copyright (C) 2017 Intel Corporation
   6 * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
   7 */
   8
   9#include <linux/acpi.h>
  10#include <linux/module.h>
  11#include <linux/usb/tcpm.h>
  12#include <linux/interrupt.h>
  13#include <linux/platform_device.h>
  14#include <linux/mfd/intel_soc_pmic.h>
  15
  16/* Register offsets */
  17#define WCOVE_CHGRIRQ0          0x4e09
  18
  19#define USBC_CONTROL1           0x7001
  20#define USBC_CONTROL2           0x7002
  21#define USBC_CONTROL3           0x7003
  22#define USBC_CC1_CTRL           0x7004
  23#define USBC_CC2_CTRL           0x7005
  24#define USBC_STATUS1            0x7007
  25#define USBC_STATUS2            0x7008
  26#define USBC_STATUS3            0x7009
  27#define USBC_CC1                0x700a
  28#define USBC_CC2                0x700b
  29#define USBC_CC1_STATUS         0x700c
  30#define USBC_CC2_STATUS         0x700d
  31#define USBC_IRQ1               0x7015
  32#define USBC_IRQ2               0x7016
  33#define USBC_IRQMASK1           0x7017
  34#define USBC_IRQMASK2           0x7018
  35#define USBC_PDCFG2             0x701a
  36#define USBC_PDCFG3             0x701b
  37#define USBC_PDSTATUS           0x701c
  38#define USBC_RXSTATUS           0x701d
  39#define USBC_RXINFO             0x701e
  40#define USBC_TXCMD              0x701f
  41#define USBC_TXINFO             0x7020
  42#define USBC_RX_DATA            0x7028
  43#define USBC_TX_DATA            0x7047
  44
  45/* Register bits */
  46
  47#define USBC_CONTROL1_MODE_MASK         0x3
  48#define   USBC_CONTROL1_MODE_SNK        0
  49#define   USBC_CONTROL1_MODE_SNKACC     1
  50#define   USBC_CONTROL1_MODE_SRC        2
  51#define   USBC_CONTROL1_MODE_SRCACC     3
  52#define   USBC_CONTROL1_MODE_DRP        4
  53#define   USBC_CONTROL1_MODE_DRPACC     5
  54#define   USBC_CONTROL1_MODE_TEST       7
  55#define USBC_CONTROL1_CURSRC_MASK       0xc
  56#define   USBC_CONTROL1_CURSRC_UA_0     (0 << 3)
  57#define   USBC_CONTROL1_CURSRC_UA_80    (1 << 3)
  58#define   USBC_CONTROL1_CURSRC_UA_180   (2 << 3)
  59#define   USBC_CONTROL1_CURSRC_UA_330   (3 << 3)
  60#define USBC_CONTROL1_DRPTOGGLE_RANDOM  0xe0
  61
  62#define USBC_CONTROL2_UNATT_SNK         BIT(0)
  63#define USBC_CONTROL2_UNATT_SRC         BIT(1)
  64#define USBC_CONTROL2_DIS_ST            BIT(2)
  65
  66#define USBC_CONTROL3_DET_DIS           BIT(0)
  67#define USBC_CONTROL3_PD_DIS            BIT(1)
  68#define USBC_CONTROL3_RESETPHY          BIT(2)
  69
  70#define USBC_CC_CTRL_PU_EN              BIT(0)
  71#define USBC_CC_CTRL_VCONN_EN           BIT(1)
  72#define USBC_CC_CTRL_TX_EN              BIT(2)
  73#define USBC_CC_CTRL_PD_EN              BIT(3)
  74#define USBC_CC_CTRL_CDET_EN            BIT(4)
  75#define USBC_CC_CTRL_RDET_EN            BIT(5)
  76#define USBC_CC_CTRL_ADC_EN             BIT(6)
  77#define USBC_CC_CTRL_VBUSOK             BIT(7)
  78
  79#define USBC_STATUS1_DET_ONGOING        BIT(6)
  80#define USBC_STATUS1_RSLT(r)            ((r) & 0xf)
  81#define USBC_RSLT_NOTHING               0
  82#define USBC_RSLT_SRC_DEFAULT           1
  83#define USBC_RSLT_SRC_1_5A              2
  84#define USBC_RSLT_SRC_3_0A              3
  85#define USBC_RSLT_SNK                   4
  86#define USBC_RSLT_DEBUG_ACC             5
  87#define USBC_RSLT_AUDIO_ACC             6
  88#define USBC_RSLT_UNDEF                 15
  89#define USBC_STATUS1_ORIENT(r)          (((r) >> 4) & 0x3)
  90#define USBC_ORIENT_NORMAL              1
  91#define USBC_ORIENT_REVERSE             2
  92
  93#define USBC_STATUS2_VBUS_REQ           BIT(5)
  94
  95#define UCSC_CC_STATUS_SNK_RP           BIT(0)
  96#define UCSC_CC_STATUS_PWRDEFSNK        BIT(1)
  97#define UCSC_CC_STATUS_PWR_1P5A_SNK     BIT(2)
  98#define UCSC_CC_STATUS_PWR_3A_SNK       BIT(3)
  99#define UCSC_CC_STATUS_SRC_RP           BIT(4)
 100#define UCSC_CC_STATUS_RX(r)            (((r) >> 5) & 0x3)
 101#define   USBC_CC_STATUS_RD             1
 102#define   USBC_CC_STATUS_RA             2
 103
 104#define USBC_IRQ1_ADCDONE1              BIT(2)
 105#define USBC_IRQ1_OVERTEMP              BIT(1)
 106#define USBC_IRQ1_SHORT                 BIT(0)
 107
 108#define USBC_IRQ2_CC_CHANGE             BIT(7)
 109#define USBC_IRQ2_RX_PD                 BIT(6)
 110#define USBC_IRQ2_RX_HR                 BIT(5)
 111#define USBC_IRQ2_RX_CR                 BIT(4)
 112#define USBC_IRQ2_TX_SUCCESS            BIT(3)
 113#define USBC_IRQ2_TX_FAIL               BIT(2)
 114
 115#define USBC_IRQMASK1_ALL       (USBC_IRQ1_ADCDONE1 | USBC_IRQ1_OVERTEMP | \
 116                                 USBC_IRQ1_SHORT)
 117
 118#define USBC_IRQMASK2_ALL       (USBC_IRQ2_CC_CHANGE | USBC_IRQ2_RX_PD | \
 119                                 USBC_IRQ2_RX_HR | USBC_IRQ2_RX_CR | \
 120                                 USBC_IRQ2_TX_SUCCESS | USBC_IRQ2_TX_FAIL)
 121
 122#define USBC_PDCFG2_SOP                 BIT(0)
 123#define USBC_PDCFG2_SOP_P               BIT(1)
 124#define USBC_PDCFG2_SOP_PP              BIT(2)
 125#define USBC_PDCFG2_SOP_P_DEBUG         BIT(3)
 126#define USBC_PDCFG2_SOP_PP_DEBUG        BIT(4)
 127
 128#define USBC_PDCFG3_DATAROLE_SHIFT      1
 129#define USBC_PDCFG3_SOP_SHIFT           2
 130
 131#define USBC_RXSTATUS_RXCLEAR           BIT(0)
 132#define USBC_RXSTATUS_RXDATA            BIT(7)
 133
 134#define USBC_RXINFO_RXBYTES(i)          (((i) >> 3) & 0x1f)
 135
 136#define USBC_TXCMD_BUF_RDY              BIT(0)
 137#define USBC_TXCMD_START                BIT(1)
 138#define USBC_TXCMD_NOP                  (0 << 5)
 139#define USBC_TXCMD_MSG                  (1 << 5)
 140#define USBC_TXCMD_CR                   (2 << 5)
 141#define USBC_TXCMD_HR                   (3 << 5)
 142#define USBC_TXCMD_BIST                 (4 << 5)
 143
 144#define USBC_TXINFO_RETRIES(d)          (d << 3)
 145
 146struct wcove_typec {
 147        struct mutex lock; /* device lock */
 148        struct device *dev;
 149        struct regmap *regmap;
 150        guid_t guid;
 151
 152        bool vbus;
 153
 154        struct tcpc_dev tcpc;
 155        struct tcpm_port *tcpm;
 156};
 157
 158#define tcpc_to_wcove(_tcpc_) container_of(_tcpc_, struct wcove_typec, tcpc)
 159
 160enum wcove_typec_func {
 161        WCOVE_FUNC_DRIVE_VBUS = 1,
 162        WCOVE_FUNC_ORIENTATION,
 163        WCOVE_FUNC_ROLE,
 164        WCOVE_FUNC_DRIVE_VCONN,
 165};
 166
 167enum wcove_typec_orientation {
 168        WCOVE_ORIENTATION_NORMAL,
 169        WCOVE_ORIENTATION_REVERSE,
 170};
 171
 172enum wcove_typec_role {
 173        WCOVE_ROLE_HOST,
 174        WCOVE_ROLE_DEVICE,
 175};
 176
 177#define WCOVE_DSM_UUID          "482383f0-2876-4e49-8685-db66211af037"
 178
 179static int wcove_typec_func(struct wcove_typec *wcove,
 180                            enum wcove_typec_func func, int param)
 181{
 182        union acpi_object *obj;
 183        union acpi_object tmp;
 184        union acpi_object argv4 = ACPI_INIT_DSM_ARGV4(1, &tmp);
 185
 186        tmp.type = ACPI_TYPE_INTEGER;
 187        tmp.integer.value = param;
 188
 189        obj = acpi_evaluate_dsm(ACPI_HANDLE(wcove->dev), &wcove->guid, 1, func,
 190                                &argv4);
 191        if (!obj) {
 192                dev_err(wcove->dev, "%s: failed to evaluate _DSM\n", __func__);
 193                return -EIO;
 194        }
 195
 196        ACPI_FREE(obj);
 197        return 0;
 198}
 199
 200static int wcove_init(struct tcpc_dev *tcpc)
 201{
 202        struct wcove_typec *wcove = tcpc_to_wcove(tcpc);
 203        int ret;
 204
 205        ret = regmap_write(wcove->regmap, USBC_CONTROL1, 0);
 206        if (ret)
 207                return ret;
 208
 209        /* Unmask everything */
 210        ret = regmap_write(wcove->regmap, USBC_IRQMASK1, 0);
 211        if (ret)
 212                return ret;
 213
 214        return regmap_write(wcove->regmap, USBC_IRQMASK2, 0);
 215}
 216
 217static int wcove_get_vbus(struct tcpc_dev *tcpc)
 218{
 219        struct wcove_typec *wcove = tcpc_to_wcove(tcpc);
 220        unsigned int cc1ctrl;
 221        int ret;
 222
 223        ret = regmap_read(wcove->regmap, USBC_CC1_CTRL, &cc1ctrl);
 224        if (ret)
 225                return ret;
 226
 227        wcove->vbus = !!(cc1ctrl & USBC_CC_CTRL_VBUSOK);
 228
 229        return wcove->vbus;
 230}
 231
 232static int wcove_set_vbus(struct tcpc_dev *tcpc, bool on, bool sink)
 233{
 234        struct wcove_typec *wcove = tcpc_to_wcove(tcpc);
 235
 236        return wcove_typec_func(wcove, WCOVE_FUNC_DRIVE_VBUS, on);
 237}
 238
 239static int wcove_set_vconn(struct tcpc_dev *tcpc, bool on)
 240{
 241        struct wcove_typec *wcove = tcpc_to_wcove(tcpc);
 242
 243        return wcove_typec_func(wcove, WCOVE_FUNC_DRIVE_VCONN, on);
 244}
 245
 246static enum typec_cc_status wcove_to_typec_cc(unsigned int cc)
 247{
 248        if (cc & UCSC_CC_STATUS_SNK_RP) {
 249                if (cc & UCSC_CC_STATUS_PWRDEFSNK)
 250                        return TYPEC_CC_RP_DEF;
 251                else if (cc & UCSC_CC_STATUS_PWR_1P5A_SNK)
 252                        return TYPEC_CC_RP_1_5;
 253                else if (cc & UCSC_CC_STATUS_PWR_3A_SNK)
 254                        return TYPEC_CC_RP_3_0;
 255        } else {
 256                switch (UCSC_CC_STATUS_RX(cc)) {
 257                case USBC_CC_STATUS_RD:
 258                        return TYPEC_CC_RD;
 259                case USBC_CC_STATUS_RA:
 260                        return TYPEC_CC_RA;
 261                default:
 262                        break;
 263                }
 264        }
 265        return TYPEC_CC_OPEN;
 266}
 267
 268static int wcove_get_cc(struct tcpc_dev *tcpc, enum typec_cc_status *cc1,
 269                        enum typec_cc_status *cc2)
 270{
 271        struct wcove_typec *wcove = tcpc_to_wcove(tcpc);
 272        unsigned int cc1_status;
 273        unsigned int cc2_status;
 274        int ret;
 275
 276        ret = regmap_read(wcove->regmap, USBC_CC1_STATUS, &cc1_status);
 277        if (ret)
 278                return ret;
 279
 280        ret = regmap_read(wcove->regmap, USBC_CC2_STATUS, &cc2_status);
 281        if (ret)
 282                return ret;
 283
 284        *cc1 = wcove_to_typec_cc(cc1_status);
 285        *cc2 = wcove_to_typec_cc(cc2_status);
 286
 287        return 0;
 288}
 289
 290static int wcove_set_cc(struct tcpc_dev *tcpc, enum typec_cc_status cc)
 291{
 292        struct wcove_typec *wcove = tcpc_to_wcove(tcpc);
 293        unsigned int ctrl;
 294
 295        switch (cc) {
 296        case TYPEC_CC_RD:
 297                ctrl = USBC_CONTROL1_MODE_SNK;
 298                break;
 299        case TYPEC_CC_RP_DEF:
 300                ctrl = USBC_CONTROL1_CURSRC_UA_80 | USBC_CONTROL1_MODE_SRC;
 301                break;
 302        case TYPEC_CC_RP_1_5:
 303                ctrl = USBC_CONTROL1_CURSRC_UA_180 | USBC_CONTROL1_MODE_SRC;
 304                break;
 305        case TYPEC_CC_RP_3_0:
 306                ctrl = USBC_CONTROL1_CURSRC_UA_330 | USBC_CONTROL1_MODE_SRC;
 307                break;
 308        case TYPEC_CC_OPEN:
 309                ctrl = 0;
 310                break;
 311        default:
 312                return -EINVAL;
 313        }
 314
 315        return regmap_write(wcove->regmap, USBC_CONTROL1, ctrl);
 316}
 317
 318static int wcove_set_polarity(struct tcpc_dev *tcpc, enum typec_cc_polarity pol)
 319{
 320        struct wcove_typec *wcove = tcpc_to_wcove(tcpc);
 321
 322        return wcove_typec_func(wcove, WCOVE_FUNC_ORIENTATION, pol);
 323}
 324
 325static int wcove_set_current_limit(struct tcpc_dev *tcpc, u32 max_ma, u32 mv)
 326{
 327        return 0;
 328}
 329
 330static int wcove_set_roles(struct tcpc_dev *tcpc, bool attached,
 331                           enum typec_role role, enum typec_data_role data)
 332{
 333        struct wcove_typec *wcove = tcpc_to_wcove(tcpc);
 334        unsigned int val;
 335        int ret;
 336
 337        ret = wcove_typec_func(wcove, WCOVE_FUNC_ROLE, data == TYPEC_HOST ?
 338                               WCOVE_ROLE_HOST : WCOVE_ROLE_DEVICE);
 339        if (ret)
 340                return ret;
 341
 342        val = role;
 343        val |= data << USBC_PDCFG3_DATAROLE_SHIFT;
 344        val |= PD_REV20 << USBC_PDCFG3_SOP_SHIFT;
 345
 346        return regmap_write(wcove->regmap, USBC_PDCFG3, val);
 347}
 348
 349static int wcove_set_pd_rx(struct tcpc_dev *tcpc, bool on)
 350{
 351        struct wcove_typec *wcove = tcpc_to_wcove(tcpc);
 352
 353        return regmap_write(wcove->regmap, USBC_PDCFG2,
 354                            on ? USBC_PDCFG2_SOP : 0);
 355}
 356
 357static int wcove_pd_transmit(struct tcpc_dev *tcpc,
 358                             enum tcpm_transmit_type type,
 359                             const struct pd_message *msg)
 360{
 361        struct wcove_typec *wcove = tcpc_to_wcove(tcpc);
 362        unsigned int info = 0;
 363        unsigned int cmd;
 364        int ret;
 365
 366        ret = regmap_read(wcove->regmap, USBC_TXCMD, &cmd);
 367        if (ret)
 368                return ret;
 369
 370        if (!(cmd & USBC_TXCMD_BUF_RDY)) {
 371                dev_warn(wcove->dev, "%s: Last transmission still ongoing!",
 372                         __func__);
 373                return -EBUSY;
 374        }
 375
 376        if (msg) {
 377                const u8 *data = (void *)msg;
 378                int i;
 379
 380                for (i = 0; i < pd_header_cnt(msg->header) * 4 + 2; i++) {
 381                        ret = regmap_write(wcove->regmap, USBC_TX_DATA + i,
 382                                           data[i]);
 383                        if (ret)
 384                                return ret;
 385                }
 386        }
 387
 388        switch (type) {
 389        case TCPC_TX_SOP:
 390        case TCPC_TX_SOP_PRIME:
 391        case TCPC_TX_SOP_PRIME_PRIME:
 392        case TCPC_TX_SOP_DEBUG_PRIME:
 393        case TCPC_TX_SOP_DEBUG_PRIME_PRIME:
 394                info = type + 1;
 395                cmd = USBC_TXCMD_MSG;
 396                break;
 397        case TCPC_TX_HARD_RESET:
 398                cmd = USBC_TXCMD_HR;
 399                break;
 400        case TCPC_TX_CABLE_RESET:
 401                cmd = USBC_TXCMD_CR;
 402                break;
 403        case TCPC_TX_BIST_MODE_2:
 404                cmd = USBC_TXCMD_BIST;
 405                break;
 406        default:
 407                return -EINVAL;
 408        }
 409
 410        /* NOTE Setting maximum number of retries (7) */
 411        ret = regmap_write(wcove->regmap, USBC_TXINFO,
 412                           info | USBC_TXINFO_RETRIES(7));
 413        if (ret)
 414                return ret;
 415
 416        return regmap_write(wcove->regmap, USBC_TXCMD, cmd | USBC_TXCMD_START);
 417}
 418
 419static int wcove_start_drp_toggling(struct tcpc_dev *tcpc,
 420                                    enum typec_cc_status cc)
 421{
 422        struct wcove_typec *wcove = tcpc_to_wcove(tcpc);
 423        unsigned int usbc_ctrl;
 424
 425        usbc_ctrl = USBC_CONTROL1_MODE_DRP | USBC_CONTROL1_DRPTOGGLE_RANDOM;
 426
 427        switch (cc) {
 428        case TYPEC_CC_RP_1_5:
 429                usbc_ctrl |= USBC_CONTROL1_CURSRC_UA_180;
 430                break;
 431        case TYPEC_CC_RP_3_0:
 432                usbc_ctrl |= USBC_CONTROL1_CURSRC_UA_330;
 433                break;
 434        default:
 435                usbc_ctrl |= USBC_CONTROL1_CURSRC_UA_80;
 436                break;
 437        }
 438
 439        return regmap_write(wcove->regmap, USBC_CONTROL1, usbc_ctrl);
 440}
 441
 442static int wcove_read_rx_buffer(struct wcove_typec *wcove, void *msg)
 443{
 444        unsigned int info;
 445        int ret;
 446        int i;
 447
 448        ret = regmap_read(wcove->regmap, USBC_RXINFO, &info);
 449        if (ret)
 450                return ret;
 451
 452        /* FIXME: Check that USBC_RXINFO_RXBYTES(info) matches the header */
 453
 454        for (i = 0; i < USBC_RXINFO_RXBYTES(info); i++) {
 455                ret = regmap_read(wcove->regmap, USBC_RX_DATA + i, msg + i);
 456                if (ret)
 457                        return ret;
 458        }
 459
 460        return regmap_write(wcove->regmap, USBC_RXSTATUS,
 461                            USBC_RXSTATUS_RXCLEAR);
 462}
 463
 464static irqreturn_t wcove_typec_irq(int irq, void *data)
 465{
 466        struct wcove_typec *wcove = data;
 467        unsigned int usbc_irq1 = 0;
 468        unsigned int usbc_irq2 = 0;
 469        unsigned int cc1ctrl;
 470        int ret;
 471
 472        mutex_lock(&wcove->lock);
 473
 474        /* Read.. */
 475        ret = regmap_read(wcove->regmap, USBC_IRQ1, &usbc_irq1);
 476        if (ret)
 477                goto err;
 478
 479        ret = regmap_read(wcove->regmap, USBC_IRQ2, &usbc_irq2);
 480        if (ret)
 481                goto err;
 482
 483        ret = regmap_read(wcove->regmap, USBC_CC1_CTRL, &cc1ctrl);
 484        if (ret)
 485                goto err;
 486
 487        if (!wcove->tcpm)
 488                goto err;
 489
 490        /* ..check.. */
 491        if (usbc_irq1 & USBC_IRQ1_OVERTEMP) {
 492                dev_err(wcove->dev, "VCONN Switch Over Temperature!\n");
 493                wcove_typec_func(wcove, WCOVE_FUNC_DRIVE_VCONN, false);
 494                /* REVISIT: Report an error? */
 495        }
 496
 497        if (usbc_irq1 & USBC_IRQ1_SHORT) {
 498                dev_err(wcove->dev, "VCONN Switch Short Circuit!\n");
 499                wcove_typec_func(wcove, WCOVE_FUNC_DRIVE_VCONN, false);
 500                /* REVISIT: Report an error? */
 501        }
 502
 503        if (wcove->vbus != !!(cc1ctrl & USBC_CC_CTRL_VBUSOK))
 504                tcpm_vbus_change(wcove->tcpm);
 505
 506        /* REVISIT: See if tcpm code can be made to consider Type-C HW FSMs */
 507        if (usbc_irq2 & USBC_IRQ2_CC_CHANGE)
 508                tcpm_cc_change(wcove->tcpm);
 509
 510        if (usbc_irq2 & USBC_IRQ2_RX_PD) {
 511                unsigned int status;
 512
 513                /*
 514                 * FIXME: Need to check if TX is ongoing and report
 515                 * TX_DIREGARDED if needed?
 516                 */
 517
 518                ret = regmap_read(wcove->regmap, USBC_RXSTATUS, &status);
 519                if (ret)
 520                        goto err;
 521
 522                /* Flush all buffers */
 523                while (status & USBC_RXSTATUS_RXDATA) {
 524                        struct pd_message msg;
 525
 526                        ret = wcove_read_rx_buffer(wcove, &msg);
 527                        if (ret) {
 528                                dev_err(wcove->dev, "%s: RX read failed\n",
 529                                        __func__);
 530                                goto err;
 531                        }
 532
 533                        tcpm_pd_receive(wcove->tcpm, &msg);
 534
 535                        ret = regmap_read(wcove->regmap, USBC_RXSTATUS,
 536                                          &status);
 537                        if (ret)
 538                                goto err;
 539                }
 540        }
 541
 542        if (usbc_irq2 & USBC_IRQ2_RX_HR)
 543                tcpm_pd_hard_reset(wcove->tcpm);
 544
 545        /* REVISIT: if (usbc_irq2 & USBC_IRQ2_RX_CR) */
 546
 547        if (usbc_irq2 & USBC_IRQ2_TX_SUCCESS)
 548                tcpm_pd_transmit_complete(wcove->tcpm, TCPC_TX_SUCCESS);
 549
 550        if (usbc_irq2 & USBC_IRQ2_TX_FAIL)
 551                tcpm_pd_transmit_complete(wcove->tcpm, TCPC_TX_FAILED);
 552
 553err:
 554        /* ..and clear. */
 555        if (usbc_irq1) {
 556                ret = regmap_write(wcove->regmap, USBC_IRQ1, usbc_irq1);
 557                if (ret)
 558                        dev_WARN(wcove->dev, "%s failed to clear IRQ1\n",
 559                                 __func__);
 560        }
 561
 562        if (usbc_irq2) {
 563                ret = regmap_write(wcove->regmap, USBC_IRQ2, usbc_irq2);
 564                if (ret)
 565                        dev_WARN(wcove->dev, "%s failed to clear IRQ2\n",
 566                                 __func__);
 567        }
 568
 569        /* REVISIT: Clear WhiskeyCove CHGR Type-C interrupt */
 570        regmap_write(wcove->regmap, WCOVE_CHGRIRQ0, BIT(5));
 571
 572        mutex_unlock(&wcove->lock);
 573        return IRQ_HANDLED;
 574}
 575
 576/*
 577 * The following power levels should be safe to use with Joule board.
 578 */
 579static const u32 src_pdo[] = {
 580        PDO_FIXED(5000, 1500, PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |
 581                  PDO_FIXED_USB_COMM),
 582};
 583
 584static const u32 snk_pdo[] = {
 585        PDO_FIXED(5000, 500, PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |
 586                  PDO_FIXED_USB_COMM),
 587        PDO_VAR(5000, 12000, 3000),
 588};
 589
 590static struct tcpc_config wcove_typec_config = {
 591        .src_pdo = src_pdo,
 592        .nr_src_pdo = ARRAY_SIZE(src_pdo),
 593        .snk_pdo = snk_pdo,
 594        .nr_snk_pdo = ARRAY_SIZE(snk_pdo),
 595
 596        .operating_snk_mw = 15000,
 597
 598        .type = TYPEC_PORT_DRP,
 599        .data = TYPEC_PORT_DRD,
 600        .default_role = TYPEC_SINK,
 601};
 602
 603static int wcove_typec_probe(struct platform_device *pdev)
 604{
 605        struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
 606        struct wcove_typec *wcove;
 607        int irq;
 608        int ret;
 609
 610        wcove = devm_kzalloc(&pdev->dev, sizeof(*wcove), GFP_KERNEL);
 611        if (!wcove)
 612                return -ENOMEM;
 613
 614        mutex_init(&wcove->lock);
 615        wcove->dev = &pdev->dev;
 616        wcove->regmap = pmic->regmap;
 617
 618        irq = regmap_irq_get_virq(pmic->irq_chip_data_chgr,
 619                                  platform_get_irq(pdev, 0));
 620        if (irq < 0)
 621                return irq;
 622
 623        ret = guid_parse(WCOVE_DSM_UUID, &wcove->guid);
 624        if (ret)
 625                return ret;
 626
 627        if (!acpi_check_dsm(ACPI_HANDLE(&pdev->dev), &wcove->guid, 0, 0x1f)) {
 628                dev_err(&pdev->dev, "Missing _DSM functions\n");
 629                return -ENODEV;
 630        }
 631
 632        wcove->tcpc.init = wcove_init;
 633        wcove->tcpc.get_vbus = wcove_get_vbus;
 634        wcove->tcpc.set_vbus = wcove_set_vbus;
 635        wcove->tcpc.set_cc = wcove_set_cc;
 636        wcove->tcpc.get_cc = wcove_get_cc;
 637        wcove->tcpc.set_polarity = wcove_set_polarity;
 638        wcove->tcpc.set_vconn = wcove_set_vconn;
 639        wcove->tcpc.set_current_limit = wcove_set_current_limit;
 640        wcove->tcpc.start_drp_toggling = wcove_start_drp_toggling;
 641
 642        wcove->tcpc.set_pd_rx = wcove_set_pd_rx;
 643        wcove->tcpc.set_roles = wcove_set_roles;
 644        wcove->tcpc.pd_transmit = wcove_pd_transmit;
 645
 646        wcove->tcpc.config = &wcove_typec_config;
 647
 648        wcove->tcpm = tcpm_register_port(wcove->dev, &wcove->tcpc);
 649        if (IS_ERR(wcove->tcpm))
 650                return PTR_ERR(wcove->tcpm);
 651
 652        ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
 653                                        wcove_typec_irq, IRQF_ONESHOT,
 654                                        "wcove_typec", wcove);
 655        if (ret) {
 656                tcpm_unregister_port(wcove->tcpm);
 657                return ret;
 658        }
 659
 660        platform_set_drvdata(pdev, wcove);
 661        return 0;
 662}
 663
 664static int wcove_typec_remove(struct platform_device *pdev)
 665{
 666        struct wcove_typec *wcove = platform_get_drvdata(pdev);
 667        unsigned int val;
 668
 669        /* Mask everything */
 670        regmap_read(wcove->regmap, USBC_IRQMASK1, &val);
 671        regmap_write(wcove->regmap, USBC_IRQMASK1, val | USBC_IRQMASK1_ALL);
 672        regmap_read(wcove->regmap, USBC_IRQMASK2, &val);
 673        regmap_write(wcove->regmap, USBC_IRQMASK2, val | USBC_IRQMASK2_ALL);
 674
 675        tcpm_unregister_port(wcove->tcpm);
 676
 677        return 0;
 678}
 679
 680static struct platform_driver wcove_typec_driver = {
 681        .driver = {
 682                .name           = "bxt_wcove_usbc",
 683        },
 684        .probe                  = wcove_typec_probe,
 685        .remove                 = wcove_typec_remove,
 686};
 687
 688module_platform_driver(wcove_typec_driver);
 689
 690MODULE_AUTHOR("Intel Corporation");
 691MODULE_LICENSE("GPL v2");
 692MODULE_DESCRIPTION("WhiskeyCove PMIC USB Type-C PHY driver");
 693MODULE_ALIAS("platform:bxt_wcove_usbc");
 694