linux/drivers/usb/typec/tcpm/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_toggling(struct tcpc_dev *tcpc,
 420                                enum typec_port_type port_type,
 421                                enum typec_cc_status cc)
 422{
 423        struct wcove_typec *wcove = tcpc_to_wcove(tcpc);
 424        unsigned int usbc_ctrl;
 425
 426        if (port_type != TYPEC_PORT_DRP)
 427                return -EOPNOTSUPP;
 428
 429        usbc_ctrl = USBC_CONTROL1_MODE_DRP | USBC_CONTROL1_DRPTOGGLE_RANDOM;
 430
 431        switch (cc) {
 432        case TYPEC_CC_RP_1_5:
 433                usbc_ctrl |= USBC_CONTROL1_CURSRC_UA_180;
 434                break;
 435        case TYPEC_CC_RP_3_0:
 436                usbc_ctrl |= USBC_CONTROL1_CURSRC_UA_330;
 437                break;
 438        default:
 439                usbc_ctrl |= USBC_CONTROL1_CURSRC_UA_80;
 440                break;
 441        }
 442
 443        return regmap_write(wcove->regmap, USBC_CONTROL1, usbc_ctrl);
 444}
 445
 446static int wcove_read_rx_buffer(struct wcove_typec *wcove, void *msg)
 447{
 448        unsigned int info;
 449        int ret;
 450        int i;
 451
 452        ret = regmap_read(wcove->regmap, USBC_RXINFO, &info);
 453        if (ret)
 454                return ret;
 455
 456        /* FIXME: Check that USBC_RXINFO_RXBYTES(info) matches the header */
 457
 458        for (i = 0; i < USBC_RXINFO_RXBYTES(info); i++) {
 459                ret = regmap_read(wcove->regmap, USBC_RX_DATA + i, msg + i);
 460                if (ret)
 461                        return ret;
 462        }
 463
 464        return regmap_write(wcove->regmap, USBC_RXSTATUS,
 465                            USBC_RXSTATUS_RXCLEAR);
 466}
 467
 468static irqreturn_t wcove_typec_irq(int irq, void *data)
 469{
 470        struct wcove_typec *wcove = data;
 471        unsigned int usbc_irq1 = 0;
 472        unsigned int usbc_irq2 = 0;
 473        unsigned int cc1ctrl;
 474        int ret;
 475
 476        mutex_lock(&wcove->lock);
 477
 478        /* Read.. */
 479        ret = regmap_read(wcove->regmap, USBC_IRQ1, &usbc_irq1);
 480        if (ret)
 481                goto err;
 482
 483        ret = regmap_read(wcove->regmap, USBC_IRQ2, &usbc_irq2);
 484        if (ret)
 485                goto err;
 486
 487        ret = regmap_read(wcove->regmap, USBC_CC1_CTRL, &cc1ctrl);
 488        if (ret)
 489                goto err;
 490
 491        if (!wcove->tcpm)
 492                goto err;
 493
 494        /* ..check.. */
 495        if (usbc_irq1 & USBC_IRQ1_OVERTEMP) {
 496                dev_err(wcove->dev, "VCONN Switch Over Temperature!\n");
 497                wcove_typec_func(wcove, WCOVE_FUNC_DRIVE_VCONN, false);
 498                /* REVISIT: Report an error? */
 499        }
 500
 501        if (usbc_irq1 & USBC_IRQ1_SHORT) {
 502                dev_err(wcove->dev, "VCONN Switch Short Circuit!\n");
 503                wcove_typec_func(wcove, WCOVE_FUNC_DRIVE_VCONN, false);
 504                /* REVISIT: Report an error? */
 505        }
 506
 507        if (wcove->vbus != !!(cc1ctrl & USBC_CC_CTRL_VBUSOK))
 508                tcpm_vbus_change(wcove->tcpm);
 509
 510        /* REVISIT: See if tcpm code can be made to consider Type-C HW FSMs */
 511        if (usbc_irq2 & USBC_IRQ2_CC_CHANGE)
 512                tcpm_cc_change(wcove->tcpm);
 513
 514        if (usbc_irq2 & USBC_IRQ2_RX_PD) {
 515                unsigned int status;
 516
 517                /*
 518                 * FIXME: Need to check if TX is ongoing and report
 519                 * TX_DIREGARDED if needed?
 520                 */
 521
 522                ret = regmap_read(wcove->regmap, USBC_RXSTATUS, &status);
 523                if (ret)
 524                        goto err;
 525
 526                /* Flush all buffers */
 527                while (status & USBC_RXSTATUS_RXDATA) {
 528                        struct pd_message msg;
 529
 530                        ret = wcove_read_rx_buffer(wcove, &msg);
 531                        if (ret) {
 532                                dev_err(wcove->dev, "%s: RX read failed\n",
 533                                        __func__);
 534                                goto err;
 535                        }
 536
 537                        tcpm_pd_receive(wcove->tcpm, &msg);
 538
 539                        ret = regmap_read(wcove->regmap, USBC_RXSTATUS,
 540                                          &status);
 541                        if (ret)
 542                                goto err;
 543                }
 544        }
 545
 546        if (usbc_irq2 & USBC_IRQ2_RX_HR)
 547                tcpm_pd_hard_reset(wcove->tcpm);
 548
 549        /* REVISIT: if (usbc_irq2 & USBC_IRQ2_RX_CR) */
 550
 551        if (usbc_irq2 & USBC_IRQ2_TX_SUCCESS)
 552                tcpm_pd_transmit_complete(wcove->tcpm, TCPC_TX_SUCCESS);
 553
 554        if (usbc_irq2 & USBC_IRQ2_TX_FAIL)
 555                tcpm_pd_transmit_complete(wcove->tcpm, TCPC_TX_FAILED);
 556
 557err:
 558        /* ..and clear. */
 559        if (usbc_irq1) {
 560                ret = regmap_write(wcove->regmap, USBC_IRQ1, usbc_irq1);
 561                if (ret)
 562                        dev_WARN(wcove->dev, "%s failed to clear IRQ1\n",
 563                                 __func__);
 564        }
 565
 566        if (usbc_irq2) {
 567                ret = regmap_write(wcove->regmap, USBC_IRQ2, usbc_irq2);
 568                if (ret)
 569                        dev_WARN(wcove->dev, "%s failed to clear IRQ2\n",
 570                                 __func__);
 571        }
 572
 573        /* REVISIT: Clear WhiskeyCove CHGR Type-C interrupt */
 574        regmap_write(wcove->regmap, WCOVE_CHGRIRQ0, BIT(5));
 575
 576        mutex_unlock(&wcove->lock);
 577        return IRQ_HANDLED;
 578}
 579
 580/*
 581 * The following power levels should be safe to use with Joule board.
 582 */
 583static const u32 src_pdo[] = {
 584        PDO_FIXED(5000, 1500, PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |
 585                  PDO_FIXED_USB_COMM),
 586};
 587
 588static const u32 snk_pdo[] = {
 589        PDO_FIXED(5000, 500, PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |
 590                  PDO_FIXED_USB_COMM),
 591        PDO_VAR(5000, 12000, 3000),
 592};
 593
 594static const struct property_entry wcove_props[] = {
 595        PROPERTY_ENTRY_STRING("data-role", "dual"),
 596        PROPERTY_ENTRY_STRING("power-role", "dual"),
 597        PROPERTY_ENTRY_STRING("try-power-role", "sink"),
 598        PROPERTY_ENTRY_U32_ARRAY("source-pdos", src_pdo),
 599        PROPERTY_ENTRY_U32_ARRAY("sink-pdos", snk_pdo),
 600        PROPERTY_ENTRY_U32("op-sink-microwatt", 15000),
 601        { }
 602};
 603
 604static int wcove_typec_probe(struct platform_device *pdev)
 605{
 606        struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
 607        struct wcove_typec *wcove;
 608        int irq;
 609        int ret;
 610
 611        wcove = devm_kzalloc(&pdev->dev, sizeof(*wcove), GFP_KERNEL);
 612        if (!wcove)
 613                return -ENOMEM;
 614
 615        mutex_init(&wcove->lock);
 616        wcove->dev = &pdev->dev;
 617        wcove->regmap = pmic->regmap;
 618
 619        irq = platform_get_irq(pdev, 0);
 620        if (irq < 0) {
 621                dev_err(&pdev->dev, "Failed to get IRQ: %d\n", irq);
 622                return irq;
 623        }
 624
 625        irq = regmap_irq_get_virq(pmic->irq_chip_data_chgr, irq);
 626        if (irq < 0)
 627                return irq;
 628
 629        ret = guid_parse(WCOVE_DSM_UUID, &wcove->guid);
 630        if (ret)
 631                return ret;
 632
 633        if (!acpi_check_dsm(ACPI_HANDLE(&pdev->dev), &wcove->guid, 0, 0x1f)) {
 634                dev_err(&pdev->dev, "Missing _DSM functions\n");
 635                return -ENODEV;
 636        }
 637
 638        wcove->tcpc.init = wcove_init;
 639        wcove->tcpc.get_vbus = wcove_get_vbus;
 640        wcove->tcpc.set_vbus = wcove_set_vbus;
 641        wcove->tcpc.set_cc = wcove_set_cc;
 642        wcove->tcpc.get_cc = wcove_get_cc;
 643        wcove->tcpc.set_polarity = wcove_set_polarity;
 644        wcove->tcpc.set_vconn = wcove_set_vconn;
 645        wcove->tcpc.set_current_limit = wcove_set_current_limit;
 646        wcove->tcpc.start_toggling = wcove_start_toggling;
 647
 648        wcove->tcpc.set_pd_rx = wcove_set_pd_rx;
 649        wcove->tcpc.set_roles = wcove_set_roles;
 650        wcove->tcpc.pd_transmit = wcove_pd_transmit;
 651
 652        wcove->tcpc.fwnode = fwnode_create_software_node(wcove_props, NULL);
 653        if (IS_ERR(wcove->tcpc.fwnode))
 654                return PTR_ERR(wcove->tcpc.fwnode);
 655
 656        wcove->tcpm = tcpm_register_port(wcove->dev, &wcove->tcpc);
 657        if (IS_ERR(wcove->tcpm)) {
 658                fwnode_remove_software_node(wcove->tcpc.fwnode);
 659                return PTR_ERR(wcove->tcpm);
 660        }
 661
 662        ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
 663                                        wcove_typec_irq, IRQF_ONESHOT,
 664                                        "wcove_typec", wcove);
 665        if (ret) {
 666                tcpm_unregister_port(wcove->tcpm);
 667                fwnode_remove_software_node(wcove->tcpc.fwnode);
 668                return ret;
 669        }
 670
 671        platform_set_drvdata(pdev, wcove);
 672        return 0;
 673}
 674
 675static int wcove_typec_remove(struct platform_device *pdev)
 676{
 677        struct wcove_typec *wcove = platform_get_drvdata(pdev);
 678        unsigned int val;
 679
 680        /* Mask everything */
 681        regmap_read(wcove->regmap, USBC_IRQMASK1, &val);
 682        regmap_write(wcove->regmap, USBC_IRQMASK1, val | USBC_IRQMASK1_ALL);
 683        regmap_read(wcove->regmap, USBC_IRQMASK2, &val);
 684        regmap_write(wcove->regmap, USBC_IRQMASK2, val | USBC_IRQMASK2_ALL);
 685
 686        tcpm_unregister_port(wcove->tcpm);
 687        fwnode_remove_software_node(wcove->tcpc.fwnode);
 688
 689        return 0;
 690}
 691
 692static struct platform_driver wcove_typec_driver = {
 693        .driver = {
 694                .name           = "bxt_wcove_usbc",
 695        },
 696        .probe                  = wcove_typec_probe,
 697        .remove                 = wcove_typec_remove,
 698};
 699
 700module_platform_driver(wcove_typec_driver);
 701
 702MODULE_AUTHOR("Intel Corporation");
 703MODULE_LICENSE("GPL v2");
 704MODULE_DESCRIPTION("WhiskeyCove PMIC USB Type-C PHY driver");
 705MODULE_ALIAS("platform:bxt_wcove_usbc");
 706