root/drivers/usb/typec/tcpm/wcove.c

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

DEFINITIONS

This source file includes following definitions.
  1. wcove_typec_func
  2. wcove_init
  3. wcove_get_vbus
  4. wcove_set_vbus
  5. wcove_set_vconn
  6. wcove_to_typec_cc
  7. wcove_get_cc
  8. wcove_set_cc
  9. wcove_set_polarity
  10. wcove_set_current_limit
  11. wcove_set_roles
  12. wcove_set_pd_rx
  13. wcove_pd_transmit
  14. wcove_start_toggling
  15. wcove_read_rx_buffer
  16. wcove_typec_irq
  17. wcove_typec_probe
  18. wcove_typec_remove

   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 
 146 struct 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 
 160 enum wcove_typec_func {
 161         WCOVE_FUNC_DRIVE_VBUS = 1,
 162         WCOVE_FUNC_ORIENTATION,
 163         WCOVE_FUNC_ROLE,
 164         WCOVE_FUNC_DRIVE_VCONN,
 165 };
 166 
 167 enum wcove_typec_orientation {
 168         WCOVE_ORIENTATION_NORMAL,
 169         WCOVE_ORIENTATION_REVERSE,
 170 };
 171 
 172 enum wcove_typec_role {
 173         WCOVE_ROLE_HOST,
 174         WCOVE_ROLE_DEVICE,
 175 };
 176 
 177 #define WCOVE_DSM_UUID          "482383f0-2876-4e49-8685-db66211af037"
 178 
 179 static 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 
 200 static 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 
 217 static 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 
 232 static 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 
 239 static 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 
 246 static 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 
 268 static 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 
 290 static 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 
 318 static 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 
 325 static int wcove_set_current_limit(struct tcpc_dev *tcpc, u32 max_ma, u32 mv)
 326 {
 327         return 0;
 328 }
 329 
 330 static 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 
 349 static 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 
 357 static 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 
 419 static 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 
 446 static 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 
 468 static 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 
 557 err:
 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  */
 583 static const u32 src_pdo[] = {
 584         PDO_FIXED(5000, 1500, PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |
 585                   PDO_FIXED_USB_COMM),
 586 };
 587 
 588 static 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 
 594 static 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", 15000000),
 601         { }
 602 };
 603 
 604 static 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                 return irq;
 622 
 623         irq = regmap_irq_get_virq(pmic->irq_chip_data_chgr, irq);
 624         if (irq < 0)
 625                 return irq;
 626 
 627         ret = guid_parse(WCOVE_DSM_UUID, &wcove->guid);
 628         if (ret)
 629                 return ret;
 630 
 631         if (!acpi_check_dsm(ACPI_HANDLE(&pdev->dev), &wcove->guid, 0, 0x1f)) {
 632                 dev_err(&pdev->dev, "Missing _DSM functions\n");
 633                 return -ENODEV;
 634         }
 635 
 636         wcove->tcpc.init = wcove_init;
 637         wcove->tcpc.get_vbus = wcove_get_vbus;
 638         wcove->tcpc.set_vbus = wcove_set_vbus;
 639         wcove->tcpc.set_cc = wcove_set_cc;
 640         wcove->tcpc.get_cc = wcove_get_cc;
 641         wcove->tcpc.set_polarity = wcove_set_polarity;
 642         wcove->tcpc.set_vconn = wcove_set_vconn;
 643         wcove->tcpc.set_current_limit = wcove_set_current_limit;
 644         wcove->tcpc.start_toggling = wcove_start_toggling;
 645 
 646         wcove->tcpc.set_pd_rx = wcove_set_pd_rx;
 647         wcove->tcpc.set_roles = wcove_set_roles;
 648         wcove->tcpc.pd_transmit = wcove_pd_transmit;
 649 
 650         wcove->tcpc.fwnode = fwnode_create_software_node(wcove_props, NULL);
 651         if (IS_ERR(wcove->tcpc.fwnode))
 652                 return PTR_ERR(wcove->tcpc.fwnode);
 653 
 654         wcove->tcpm = tcpm_register_port(wcove->dev, &wcove->tcpc);
 655         if (IS_ERR(wcove->tcpm)) {
 656                 fwnode_remove_software_node(wcove->tcpc.fwnode);
 657                 return PTR_ERR(wcove->tcpm);
 658         }
 659 
 660         ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
 661                                         wcove_typec_irq, IRQF_ONESHOT,
 662                                         "wcove_typec", wcove);
 663         if (ret) {
 664                 tcpm_unregister_port(wcove->tcpm);
 665                 fwnode_remove_software_node(wcove->tcpc.fwnode);
 666                 return ret;
 667         }
 668 
 669         platform_set_drvdata(pdev, wcove);
 670         return 0;
 671 }
 672 
 673 static int wcove_typec_remove(struct platform_device *pdev)
 674 {
 675         struct wcove_typec *wcove = platform_get_drvdata(pdev);
 676         unsigned int val;
 677 
 678         /* Mask everything */
 679         regmap_read(wcove->regmap, USBC_IRQMASK1, &val);
 680         regmap_write(wcove->regmap, USBC_IRQMASK1, val | USBC_IRQMASK1_ALL);
 681         regmap_read(wcove->regmap, USBC_IRQMASK2, &val);
 682         regmap_write(wcove->regmap, USBC_IRQMASK2, val | USBC_IRQMASK2_ALL);
 683 
 684         tcpm_unregister_port(wcove->tcpm);
 685         fwnode_remove_software_node(wcove->tcpc.fwnode);
 686 
 687         return 0;
 688 }
 689 
 690 static struct platform_driver wcove_typec_driver = {
 691         .driver = {
 692                 .name           = "bxt_wcove_usbc",
 693         },
 694         .probe                  = wcove_typec_probe,
 695         .remove                 = wcove_typec_remove,
 696 };
 697 
 698 module_platform_driver(wcove_typec_driver);
 699 
 700 MODULE_AUTHOR("Intel Corporation");
 701 MODULE_LICENSE("GPL v2");
 702 MODULE_DESCRIPTION("WhiskeyCove PMIC USB Type-C PHY driver");
 703 MODULE_ALIAS("platform:bxt_wcove_usbc");

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