1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2023, Linaro Ltd. All rights reserved. 4 */ 5 6 #include <linux/delay.h> 7 #include <linux/err.h> 8 #include <linux/interrupt.h> 9 #include <linux/kernel.h> 10 #include <linux/mod_devicetable.h> 11 #include <linux/module.h> 12 #include <linux/of_device.h> 13 #include <linux/platform_device.h> 14 #include <linux/regmap.h> 15 #include <linux/regulator/consumer.h> 16 #include <linux/slab.h> 17 #include <linux/usb/tcpm.h> 18 #include <linux/usb/typec_mux.h> 19 #include <linux/workqueue.h> 20 #include "qcom_pmic_typec_port.h" 21 22 struct pmic_typec_port_irq_data { 23 int virq; 24 int irq; 25 struct pmic_typec_port *pmic_typec_port; 26 }; 27 28 struct pmic_typec_port { 29 struct device *dev; 30 struct tcpm_port *tcpm_port; 31 struct regmap *regmap; 32 u32 base; 33 unsigned int nr_irqs; 34 struct pmic_typec_port_irq_data *irq_data; 35 36 struct regulator *vdd_vbus; 37 38 int cc; 39 bool debouncing_cc; 40 struct delayed_work cc_debounce_dwork; 41 42 spinlock_t lock; /* Register atomicity */ 43 }; 44 45 static const char * const typec_cc_status_name[] = { 46 [TYPEC_CC_OPEN] = "Open", 47 [TYPEC_CC_RA] = "Ra", 48 [TYPEC_CC_RD] = "Rd", 49 [TYPEC_CC_RP_DEF] = "Rp-def", 50 [TYPEC_CC_RP_1_5] = "Rp-1.5", 51 [TYPEC_CC_RP_3_0] = "Rp-3.0", 52 }; 53 54 static const char *rp_unknown = "unknown"; 55 56 static const char *cc_to_name(enum typec_cc_status cc) 57 { 58 if (cc > TYPEC_CC_RP_3_0) 59 return rp_unknown; 60 61 return typec_cc_status_name[cc]; 62 } 63 64 static const char * const rp_sel_name[] = { 65 [TYPEC_SRC_RP_SEL_80UA] = "Rp-def-80uA", 66 [TYPEC_SRC_RP_SEL_180UA] = "Rp-1.5-180uA", 67 [TYPEC_SRC_RP_SEL_330UA] = "Rp-3.0-330uA", 68 }; 69 70 static const char *rp_sel_to_name(int rp_sel) 71 { 72 if (rp_sel > TYPEC_SRC_RP_SEL_330UA) 73 return rp_unknown; 74 75 return rp_sel_name[rp_sel]; 76 } 77 78 #define misc_to_cc(msic) !!(misc & CC_ORIENTATION) ? "cc1" : "cc2" 79 #define misc_to_vconn(msic) !!(misc & CC_ORIENTATION) ? "cc2" : "cc1" 80 81 static void qcom_pmic_typec_port_cc_debounce(struct work_struct *work) 82 { 83 struct pmic_typec_port *pmic_typec_port = 84 container_of(work, struct pmic_typec_port, cc_debounce_dwork.work); 85 unsigned long flags; 86 87 spin_lock_irqsave(&pmic_typec_port->lock, flags); 88 pmic_typec_port->debouncing_cc = false; 89 spin_unlock_irqrestore(&pmic_typec_port->lock, flags); 90 91 dev_dbg(pmic_typec_port->dev, "Debounce cc complete\n"); 92 } 93 94 static irqreturn_t pmic_typec_port_isr(int irq, void *dev_id) 95 { 96 struct pmic_typec_port_irq_data *irq_data = dev_id; 97 struct pmic_typec_port *pmic_typec_port = irq_data->pmic_typec_port; 98 u32 misc_stat; 99 bool vbus_change = false; 100 bool cc_change = false; 101 unsigned long flags; 102 int ret; 103 104 spin_lock_irqsave(&pmic_typec_port->lock, flags); 105 106 ret = regmap_read(pmic_typec_port->regmap, 107 pmic_typec_port->base + TYPEC_MISC_STATUS_REG, 108 &misc_stat); 109 if (ret) 110 goto done; 111 112 switch (irq_data->virq) { 113 case PMIC_TYPEC_VBUS_IRQ: 114 vbus_change = true; 115 break; 116 case PMIC_TYPEC_CC_STATE_IRQ: 117 case PMIC_TYPEC_ATTACH_DETACH_IRQ: 118 if (!pmic_typec_port->debouncing_cc) 119 cc_change = true; 120 break; 121 } 122 123 done: 124 spin_unlock_irqrestore(&pmic_typec_port->lock, flags); 125 126 if (vbus_change) 127 tcpm_vbus_change(pmic_typec_port->tcpm_port); 128 129 if (cc_change) 130 tcpm_cc_change(pmic_typec_port->tcpm_port); 131 132 return IRQ_HANDLED; 133 } 134 135 int qcom_pmic_typec_port_get_vbus(struct pmic_typec_port *pmic_typec_port) 136 { 137 struct device *dev = pmic_typec_port->dev; 138 unsigned int misc; 139 int ret; 140 141 ret = regmap_read(pmic_typec_port->regmap, 142 pmic_typec_port->base + TYPEC_MISC_STATUS_REG, 143 &misc); 144 if (ret) 145 misc = 0; 146 147 dev_dbg(dev, "get_vbus: 0x%08x detect %d\n", misc, !!(misc & TYPEC_VBUS_DETECT)); 148 149 return !!(misc & TYPEC_VBUS_DETECT); 150 } 151 152 int qcom_pmic_typec_port_set_vbus(struct pmic_typec_port *pmic_typec_port, bool on) 153 { 154 u32 sm_stat; 155 u32 val; 156 int ret; 157 158 if (on) { 159 ret = regulator_enable(pmic_typec_port->vdd_vbus); 160 if (ret) 161 return ret; 162 163 val = TYPEC_SM_VBUS_VSAFE5V; 164 } else { 165 ret = regulator_disable(pmic_typec_port->vdd_vbus); 166 if (ret) 167 return ret; 168 169 val = TYPEC_SM_VBUS_VSAFE0V; 170 } 171 172 /* Poll waiting for transition to required vSafe5V or vSafe0V */ 173 ret = regmap_read_poll_timeout(pmic_typec_port->regmap, 174 pmic_typec_port->base + TYPEC_SM_STATUS_REG, 175 sm_stat, sm_stat & val, 176 100, 250000); 177 if (ret) 178 dev_warn(pmic_typec_port->dev, "vbus vsafe%dv fail\n", on ? 5 : 0); 179 180 return 0; 181 } 182 183 int qcom_pmic_typec_port_get_cc(struct pmic_typec_port *pmic_typec_port, 184 enum typec_cc_status *cc1, 185 enum typec_cc_status *cc2) 186 { 187 struct device *dev = pmic_typec_port->dev; 188 unsigned int misc, val; 189 bool attached; 190 int ret = 0; 191 192 ret = regmap_read(pmic_typec_port->regmap, 193 pmic_typec_port->base + TYPEC_MISC_STATUS_REG, &misc); 194 if (ret) 195 goto done; 196 197 attached = !!(misc & CC_ATTACHED); 198 199 if (pmic_typec_port->debouncing_cc) { 200 ret = -EBUSY; 201 goto done; 202 } 203 204 *cc1 = TYPEC_CC_OPEN; 205 *cc2 = TYPEC_CC_OPEN; 206 207 if (!attached) 208 goto done; 209 210 if (misc & SNK_SRC_MODE) { 211 ret = regmap_read(pmic_typec_port->regmap, 212 pmic_typec_port->base + TYPEC_SRC_STATUS_REG, 213 &val); 214 if (ret) 215 goto done; 216 switch (val & DETECTED_SRC_TYPE_MASK) { 217 case SRC_RD_OPEN: 218 val = TYPEC_CC_RD; 219 break; 220 case SRC_RD_RA_VCONN: 221 val = TYPEC_CC_RD; 222 *cc1 = TYPEC_CC_RA; 223 *cc2 = TYPEC_CC_RA; 224 break; 225 default: 226 dev_warn(dev, "unexpected src status %.2x\n", val); 227 val = TYPEC_CC_RD; 228 break; 229 } 230 } else { 231 ret = regmap_read(pmic_typec_port->regmap, 232 pmic_typec_port->base + TYPEC_SNK_STATUS_REG, 233 &val); 234 if (ret) 235 goto done; 236 switch (val & DETECTED_SNK_TYPE_MASK) { 237 case SNK_RP_STD: 238 val = TYPEC_CC_RP_DEF; 239 break; 240 case SNK_RP_1P5: 241 val = TYPEC_CC_RP_1_5; 242 break; 243 case SNK_RP_3P0: 244 val = TYPEC_CC_RP_3_0; 245 break; 246 default: 247 dev_warn(dev, "unexpected snk status %.2x\n", val); 248 val = TYPEC_CC_RP_DEF; 249 break; 250 } 251 val = TYPEC_CC_RP_DEF; 252 } 253 254 if (misc & CC_ORIENTATION) 255 *cc2 = val; 256 else 257 *cc1 = val; 258 259 done: 260 dev_dbg(dev, "get_cc: misc 0x%08x cc1 0x%08x %s cc2 0x%08x %s attached %d cc=%s\n", 261 misc, *cc1, cc_to_name(*cc1), *cc2, cc_to_name(*cc2), attached, 262 misc_to_cc(misc)); 263 264 return ret; 265 } 266 267 static void qcom_pmic_set_cc_debounce(struct pmic_typec_port *pmic_typec_port) 268 { 269 pmic_typec_port->debouncing_cc = true; 270 schedule_delayed_work(&pmic_typec_port->cc_debounce_dwork, 271 msecs_to_jiffies(2)); 272 } 273 274 int qcom_pmic_typec_port_set_cc(struct pmic_typec_port *pmic_typec_port, 275 enum typec_cc_status cc) 276 { 277 struct device *dev = pmic_typec_port->dev; 278 unsigned int mode, currsrc; 279 unsigned int misc; 280 unsigned long flags; 281 int ret; 282 283 spin_lock_irqsave(&pmic_typec_port->lock, flags); 284 285 ret = regmap_read(pmic_typec_port->regmap, 286 pmic_typec_port->base + TYPEC_MISC_STATUS_REG, 287 &misc); 288 if (ret) 289 goto done; 290 291 mode = EN_SRC_ONLY; 292 293 switch (cc) { 294 case TYPEC_CC_OPEN: 295 currsrc = TYPEC_SRC_RP_SEL_80UA; 296 break; 297 case TYPEC_CC_RP_DEF: 298 currsrc = TYPEC_SRC_RP_SEL_80UA; 299 break; 300 case TYPEC_CC_RP_1_5: 301 currsrc = TYPEC_SRC_RP_SEL_180UA; 302 break; 303 case TYPEC_CC_RP_3_0: 304 currsrc = TYPEC_SRC_RP_SEL_330UA; 305 break; 306 case TYPEC_CC_RD: 307 currsrc = TYPEC_SRC_RP_SEL_80UA; 308 mode = EN_SNK_ONLY; 309 break; 310 default: 311 dev_warn(dev, "unexpected set_cc %d\n", cc); 312 ret = -EINVAL; 313 goto done; 314 } 315 316 if (mode == EN_SRC_ONLY) { 317 ret = regmap_write(pmic_typec_port->regmap, 318 pmic_typec_port->base + TYPEC_CURRSRC_CFG_REG, 319 currsrc); 320 if (ret) 321 goto done; 322 } 323 324 pmic_typec_port->cc = cc; 325 qcom_pmic_set_cc_debounce(pmic_typec_port); 326 ret = 0; 327 328 done: 329 spin_unlock_irqrestore(&pmic_typec_port->lock, flags); 330 331 dev_dbg(dev, "set_cc: currsrc=%x %s mode %s debounce %d attached %d cc=%s\n", 332 currsrc, rp_sel_to_name(currsrc), 333 mode == EN_SRC_ONLY ? "EN_SRC_ONLY" : "EN_SNK_ONLY", 334 pmic_typec_port->debouncing_cc, !!(misc & CC_ATTACHED), 335 misc_to_cc(misc)); 336 337 return ret; 338 } 339 340 int qcom_pmic_typec_port_set_vconn(struct pmic_typec_port *pmic_typec_port, bool on) 341 { 342 struct device *dev = pmic_typec_port->dev; 343 unsigned int orientation, misc, mask, value; 344 unsigned long flags; 345 int ret; 346 347 spin_lock_irqsave(&pmic_typec_port->lock, flags); 348 349 ret = regmap_read(pmic_typec_port->regmap, 350 pmic_typec_port->base + TYPEC_MISC_STATUS_REG, &misc); 351 if (ret) 352 goto done; 353 354 /* Set VCONN on the inversion of the active CC channel */ 355 orientation = (misc & CC_ORIENTATION) ? 0 : VCONN_EN_ORIENTATION; 356 if (on) { 357 mask = VCONN_EN_ORIENTATION | VCONN_EN_VALUE; 358 value = orientation | VCONN_EN_VALUE | VCONN_EN_SRC; 359 } else { 360 mask = VCONN_EN_VALUE; 361 value = 0; 362 } 363 364 ret = regmap_update_bits(pmic_typec_port->regmap, 365 pmic_typec_port->base + TYPEC_VCONN_CONTROL_REG, 366 mask, value); 367 done: 368 spin_unlock_irqrestore(&pmic_typec_port->lock, flags); 369 370 dev_dbg(dev, "set_vconn: orientation %d control 0x%08x state %s cc %s vconn %s\n", 371 orientation, value, on ? "on" : "off", misc_to_vconn(misc), misc_to_cc(misc)); 372 373 return ret; 374 } 375 376 int qcom_pmic_typec_port_start_toggling(struct pmic_typec_port *pmic_typec_port, 377 enum typec_port_type port_type, 378 enum typec_cc_status cc) 379 { 380 struct device *dev = pmic_typec_port->dev; 381 unsigned int misc; 382 u8 mode = 0; 383 unsigned long flags; 384 int ret; 385 386 switch (port_type) { 387 case TYPEC_PORT_SRC: 388 mode = EN_SRC_ONLY; 389 break; 390 case TYPEC_PORT_SNK: 391 mode = EN_SNK_ONLY; 392 break; 393 case TYPEC_PORT_DRP: 394 mode = EN_TRY_SNK; 395 break; 396 } 397 398 spin_lock_irqsave(&pmic_typec_port->lock, flags); 399 400 ret = regmap_read(pmic_typec_port->regmap, 401 pmic_typec_port->base + TYPEC_MISC_STATUS_REG, &misc); 402 if (ret) 403 goto done; 404 405 dev_dbg(dev, "start_toggling: misc 0x%08x attached %d port_type %d current cc %d new %d\n", 406 misc, !!(misc & CC_ATTACHED), port_type, pmic_typec_port->cc, cc); 407 408 qcom_pmic_set_cc_debounce(pmic_typec_port); 409 410 /* force it to toggle at least once */ 411 ret = regmap_write(pmic_typec_port->regmap, 412 pmic_typec_port->base + TYPEC_MODE_CFG_REG, 413 TYPEC_DISABLE_CMD); 414 if (ret) 415 goto done; 416 417 ret = regmap_write(pmic_typec_port->regmap, 418 pmic_typec_port->base + TYPEC_MODE_CFG_REG, 419 mode); 420 done: 421 spin_unlock_irqrestore(&pmic_typec_port->lock, flags); 422 423 return ret; 424 } 425 426 #define TYPEC_INTR_EN_CFG_1_MASK \ 427 (TYPEC_LEGACY_CABLE_INT_EN | \ 428 TYPEC_NONCOMPLIANT_LEGACY_CABLE_INT_EN | \ 429 TYPEC_TRYSOURCE_DETECT_INT_EN | \ 430 TYPEC_TRYSINK_DETECT_INT_EN | \ 431 TYPEC_CCOUT_DETACH_INT_EN | \ 432 TYPEC_CCOUT_ATTACH_INT_EN | \ 433 TYPEC_VBUS_DEASSERT_INT_EN | \ 434 TYPEC_VBUS_ASSERT_INT_EN) 435 436 #define TYPEC_INTR_EN_CFG_2_MASK \ 437 (TYPEC_STATE_MACHINE_CHANGE_INT_EN | TYPEC_VBUS_ERROR_INT_EN | \ 438 TYPEC_DEBOUNCE_DONE_INT_EN) 439 440 int qcom_pmic_typec_port_start(struct pmic_typec_port *pmic_typec_port, 441 struct tcpm_port *tcpm_port) 442 { 443 int i; 444 int mask; 445 int ret; 446 447 /* Configure interrupt sources */ 448 ret = regmap_write(pmic_typec_port->regmap, 449 pmic_typec_port->base + TYPEC_INTERRUPT_EN_CFG_1_REG, 450 TYPEC_INTR_EN_CFG_1_MASK); 451 if (ret) 452 goto done; 453 454 ret = regmap_write(pmic_typec_port->regmap, 455 pmic_typec_port->base + TYPEC_INTERRUPT_EN_CFG_2_REG, 456 TYPEC_INTR_EN_CFG_2_MASK); 457 if (ret) 458 goto done; 459 460 /* start in TRY_SNK mode */ 461 ret = regmap_write(pmic_typec_port->regmap, 462 pmic_typec_port->base + TYPEC_MODE_CFG_REG, EN_TRY_SNK); 463 if (ret) 464 goto done; 465 466 /* Configure VCONN for software control */ 467 ret = regmap_update_bits(pmic_typec_port->regmap, 468 pmic_typec_port->base + TYPEC_VCONN_CONTROL_REG, 469 VCONN_EN_SRC | VCONN_EN_VALUE, VCONN_EN_SRC); 470 if (ret) 471 goto done; 472 473 /* Set CC threshold to 1.6 Volts | tPDdebounce = 10-20ms */ 474 mask = SEL_SRC_UPPER_REF | USE_TPD_FOR_EXITING_ATTACHSRC; 475 ret = regmap_update_bits(pmic_typec_port->regmap, 476 pmic_typec_port->base + TYPEC_EXIT_STATE_CFG_REG, 477 mask, mask); 478 if (ret) 479 goto done; 480 481 pmic_typec_port->tcpm_port = tcpm_port; 482 483 for (i = 0; i < pmic_typec_port->nr_irqs; i++) 484 enable_irq(pmic_typec_port->irq_data[i].irq); 485 486 done: 487 return ret; 488 } 489 490 void qcom_pmic_typec_port_stop(struct pmic_typec_port *pmic_typec_port) 491 { 492 int i; 493 494 for (i = 0; i < pmic_typec_port->nr_irqs; i++) 495 disable_irq(pmic_typec_port->irq_data[i].irq); 496 } 497 498 struct pmic_typec_port *qcom_pmic_typec_port_alloc(struct device *dev) 499 { 500 return devm_kzalloc(dev, sizeof(struct pmic_typec_port), GFP_KERNEL); 501 } 502 503 int qcom_pmic_typec_port_probe(struct platform_device *pdev, 504 struct pmic_typec_port *pmic_typec_port, 505 struct pmic_typec_port_resources *res, 506 struct regmap *regmap, 507 u32 base) 508 { 509 struct device *dev = &pdev->dev; 510 struct pmic_typec_port_irq_data *irq_data; 511 int i, ret, irq; 512 513 if (!res->nr_irqs || res->nr_irqs > PMIC_TYPEC_MAX_IRQS) 514 return -EINVAL; 515 516 irq_data = devm_kzalloc(dev, sizeof(*irq_data) * res->nr_irqs, 517 GFP_KERNEL); 518 if (!irq_data) 519 return -ENOMEM; 520 521 pmic_typec_port->vdd_vbus = devm_regulator_get(dev, "vdd-vbus"); 522 if (IS_ERR(pmic_typec_port->vdd_vbus)) 523 return PTR_ERR(pmic_typec_port->vdd_vbus); 524 525 pmic_typec_port->dev = dev; 526 pmic_typec_port->base = base; 527 pmic_typec_port->regmap = regmap; 528 pmic_typec_port->nr_irqs = res->nr_irqs; 529 pmic_typec_port->irq_data = irq_data; 530 spin_lock_init(&pmic_typec_port->lock); 531 INIT_DELAYED_WORK(&pmic_typec_port->cc_debounce_dwork, 532 qcom_pmic_typec_port_cc_debounce); 533 534 irq = platform_get_irq(pdev, 0); 535 if (irq < 0) 536 return irq; 537 538 for (i = 0; i < res->nr_irqs; i++, irq_data++) { 539 irq = platform_get_irq_byname(pdev, 540 res->irq_params[i].irq_name); 541 if (irq < 0) 542 return irq; 543 544 irq_data->pmic_typec_port = pmic_typec_port; 545 irq_data->irq = irq; 546 irq_data->virq = res->irq_params[i].virq; 547 ret = devm_request_threaded_irq(dev, irq, NULL, pmic_typec_port_isr, 548 IRQF_ONESHOT | IRQF_NO_AUTOEN, 549 res->irq_params[i].irq_name, 550 irq_data); 551 if (ret) 552 return ret; 553 } 554 555 return 0; 556 } 557