at v6.13 71 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * USB Type-C Connector Class 4 * 5 * Copyright (C) 2017, Intel Corporation 6 * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com> 7 */ 8 9#include <linux/module.h> 10#include <linux/mutex.h> 11#include <linux/property.h> 12#include <linux/slab.h> 13#include <linux/usb/pd_vdo.h> 14#include <linux/usb/typec_mux.h> 15#include <linux/usb/typec_retimer.h> 16#include <linux/usb.h> 17 18#include "bus.h" 19#include "class.h" 20#include "pd.h" 21 22static DEFINE_IDA(typec_index_ida); 23 24const struct class typec_class = { 25 .name = "typec", 26}; 27 28/* ------------------------------------------------------------------------- */ 29/* Common attributes */ 30 31static const char * const typec_accessory_modes[] = { 32 [TYPEC_ACCESSORY_NONE] = "none", 33 [TYPEC_ACCESSORY_AUDIO] = "analog_audio", 34 [TYPEC_ACCESSORY_DEBUG] = "debug", 35}; 36 37/* Product types defined in USB PD Specification R3.0 V2.0 */ 38static const char * const product_type_ufp[8] = { 39 [IDH_PTYPE_NOT_UFP] = "not_ufp", 40 [IDH_PTYPE_HUB] = "hub", 41 [IDH_PTYPE_PERIPH] = "peripheral", 42 [IDH_PTYPE_PSD] = "psd", 43 [IDH_PTYPE_AMA] = "ama", 44}; 45 46static const char * const product_type_dfp[8] = { 47 [IDH_PTYPE_NOT_DFP] = "not_dfp", 48 [IDH_PTYPE_DFP_HUB] = "hub", 49 [IDH_PTYPE_DFP_HOST] = "host", 50 [IDH_PTYPE_DFP_PB] = "power_brick", 51}; 52 53static const char * const product_type_cable[8] = { 54 [IDH_PTYPE_NOT_CABLE] = "not_cable", 55 [IDH_PTYPE_PCABLE] = "passive", 56 [IDH_PTYPE_ACABLE] = "active", 57 [IDH_PTYPE_VPD] = "vpd", 58}; 59 60static struct usb_pd_identity *get_pd_identity(struct device *dev) 61{ 62 if (is_typec_partner(dev)) { 63 struct typec_partner *partner = to_typec_partner(dev); 64 65 return partner->identity; 66 } else if (is_typec_cable(dev)) { 67 struct typec_cable *cable = to_typec_cable(dev); 68 69 return cable->identity; 70 } 71 return NULL; 72} 73 74static const char *get_pd_product_type(struct device *dev) 75{ 76 struct typec_port *port = to_typec_port(dev->parent); 77 struct usb_pd_identity *id = get_pd_identity(dev); 78 const char *ptype = NULL; 79 80 if (is_typec_partner(dev)) { 81 if (!id) 82 return NULL; 83 84 if (port->data_role == TYPEC_HOST) 85 ptype = product_type_ufp[PD_IDH_PTYPE(id->id_header)]; 86 else 87 ptype = product_type_dfp[PD_IDH_DFP_PTYPE(id->id_header)]; 88 } else if (is_typec_cable(dev)) { 89 if (id) 90 ptype = product_type_cable[PD_IDH_PTYPE(id->id_header)]; 91 else 92 ptype = to_typec_cable(dev)->active ? 93 product_type_cable[IDH_PTYPE_ACABLE] : 94 product_type_cable[IDH_PTYPE_PCABLE]; 95 } 96 97 return ptype; 98} 99 100static ssize_t id_header_show(struct device *dev, struct device_attribute *attr, 101 char *buf) 102{ 103 struct usb_pd_identity *id = get_pd_identity(dev); 104 105 return sprintf(buf, "0x%08x\n", id->id_header); 106} 107static DEVICE_ATTR_RO(id_header); 108 109static ssize_t cert_stat_show(struct device *dev, struct device_attribute *attr, 110 char *buf) 111{ 112 struct usb_pd_identity *id = get_pd_identity(dev); 113 114 return sprintf(buf, "0x%08x\n", id->cert_stat); 115} 116static DEVICE_ATTR_RO(cert_stat); 117 118static ssize_t product_show(struct device *dev, struct device_attribute *attr, 119 char *buf) 120{ 121 struct usb_pd_identity *id = get_pd_identity(dev); 122 123 return sprintf(buf, "0x%08x\n", id->product); 124} 125static DEVICE_ATTR_RO(product); 126 127static ssize_t product_type_vdo1_show(struct device *dev, struct device_attribute *attr, 128 char *buf) 129{ 130 struct usb_pd_identity *id = get_pd_identity(dev); 131 132 return sysfs_emit(buf, "0x%08x\n", id->vdo[0]); 133} 134static DEVICE_ATTR_RO(product_type_vdo1); 135 136static ssize_t product_type_vdo2_show(struct device *dev, struct device_attribute *attr, 137 char *buf) 138{ 139 struct usb_pd_identity *id = get_pd_identity(dev); 140 141 return sysfs_emit(buf, "0x%08x\n", id->vdo[1]); 142} 143static DEVICE_ATTR_RO(product_type_vdo2); 144 145static ssize_t product_type_vdo3_show(struct device *dev, struct device_attribute *attr, 146 char *buf) 147{ 148 struct usb_pd_identity *id = get_pd_identity(dev); 149 150 return sysfs_emit(buf, "0x%08x\n", id->vdo[2]); 151} 152static DEVICE_ATTR_RO(product_type_vdo3); 153 154static struct attribute *usb_pd_id_attrs[] = { 155 &dev_attr_id_header.attr, 156 &dev_attr_cert_stat.attr, 157 &dev_attr_product.attr, 158 &dev_attr_product_type_vdo1.attr, 159 &dev_attr_product_type_vdo2.attr, 160 &dev_attr_product_type_vdo3.attr, 161 NULL 162}; 163 164static const struct attribute_group usb_pd_id_group = { 165 .name = "identity", 166 .attrs = usb_pd_id_attrs, 167}; 168 169static const struct attribute_group *usb_pd_id_groups[] = { 170 &usb_pd_id_group, 171 NULL, 172}; 173 174static void typec_product_type_notify(struct device *dev) 175{ 176 char *envp[2] = { }; 177 const char *ptype; 178 179 ptype = get_pd_product_type(dev); 180 if (!ptype) 181 return; 182 183 sysfs_notify(&dev->kobj, NULL, "type"); 184 185 envp[0] = kasprintf(GFP_KERNEL, "PRODUCT_TYPE=%s", ptype); 186 if (!envp[0]) 187 return; 188 189 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); 190 kfree(envp[0]); 191} 192 193static void typec_report_identity(struct device *dev) 194{ 195 sysfs_notify(&dev->kobj, "identity", "id_header"); 196 sysfs_notify(&dev->kobj, "identity", "cert_stat"); 197 sysfs_notify(&dev->kobj, "identity", "product"); 198 sysfs_notify(&dev->kobj, "identity", "product_type_vdo1"); 199 sysfs_notify(&dev->kobj, "identity", "product_type_vdo2"); 200 sysfs_notify(&dev->kobj, "identity", "product_type_vdo3"); 201 typec_product_type_notify(dev); 202} 203 204static ssize_t 205type_show(struct device *dev, struct device_attribute *attr, char *buf) 206{ 207 const char *ptype; 208 209 ptype = get_pd_product_type(dev); 210 if (!ptype) 211 return 0; 212 213 return sysfs_emit(buf, "%s\n", ptype); 214} 215static DEVICE_ATTR_RO(type); 216 217static ssize_t usb_power_delivery_revision_show(struct device *dev, 218 struct device_attribute *attr, 219 char *buf); 220static DEVICE_ATTR_RO(usb_power_delivery_revision); 221 222static const char * const usb_modes[] = { 223 [USB_MODE_NONE] = "none", 224 [USB_MODE_USB2] = "usb2", 225 [USB_MODE_USB3] = "usb3", 226 [USB_MODE_USB4] = "usb4" 227}; 228 229/* ------------------------------------------------------------------------- */ 230/* Alternate Modes */ 231 232static int altmode_match(struct device *dev, void *data) 233{ 234 struct typec_altmode *adev = to_typec_altmode(dev); 235 struct typec_device_id *id = data; 236 237 if (!is_typec_altmode(dev)) 238 return 0; 239 240 return ((adev->svid == id->svid) && (adev->mode == id->mode)); 241} 242 243static void typec_altmode_set_partner(struct altmode *altmode) 244{ 245 struct typec_altmode *adev = &altmode->adev; 246 struct typec_device_id id = { adev->svid, adev->mode, }; 247 struct typec_port *port = typec_altmode2port(adev); 248 struct altmode *partner; 249 struct device *dev; 250 251 dev = device_find_child(&port->dev, &id, altmode_match); 252 if (!dev) 253 return; 254 255 /* Bind the port alt mode to the partner/plug alt mode. */ 256 partner = to_altmode(to_typec_altmode(dev)); 257 altmode->partner = partner; 258 259 /* Bind the partner/plug alt mode to the port alt mode. */ 260 if (is_typec_plug(adev->dev.parent)) { 261 struct typec_plug *plug = to_typec_plug(adev->dev.parent); 262 263 partner->plug[plug->index] = altmode; 264 } else { 265 partner->partner = altmode; 266 } 267} 268 269static void typec_altmode_put_partner(struct altmode *altmode) 270{ 271 struct altmode *partner = altmode->partner; 272 struct typec_altmode *adev; 273 struct typec_altmode *partner_adev; 274 275 if (!partner) 276 return; 277 278 adev = &altmode->adev; 279 partner_adev = &partner->adev; 280 281 if (is_typec_plug(adev->dev.parent)) { 282 struct typec_plug *plug = to_typec_plug(adev->dev.parent); 283 284 partner->plug[plug->index] = NULL; 285 } else { 286 partner->partner = NULL; 287 } 288 put_device(&partner_adev->dev); 289} 290 291/** 292 * typec_altmode_update_active - Report Enter/Exit mode 293 * @adev: Handle to the alternate mode 294 * @active: True when the mode has been entered 295 * 296 * If a partner or cable plug executes Enter/Exit Mode command successfully, the 297 * drivers use this routine to report the updated state of the mode. 298 */ 299void typec_altmode_update_active(struct typec_altmode *adev, bool active) 300{ 301 char dir[6]; 302 303 if (adev->active == active) 304 return; 305 306 if (!is_typec_port(adev->dev.parent) && adev->dev.driver) { 307 if (!active) 308 module_put(adev->dev.driver->owner); 309 else 310 WARN_ON(!try_module_get(adev->dev.driver->owner)); 311 } 312 313 adev->active = active; 314 snprintf(dir, sizeof(dir), "mode%d", adev->mode); 315 sysfs_notify(&adev->dev.kobj, dir, "active"); 316 sysfs_notify(&adev->dev.kobj, NULL, "active"); 317 kobject_uevent(&adev->dev.kobj, KOBJ_CHANGE); 318} 319EXPORT_SYMBOL_GPL(typec_altmode_update_active); 320 321/** 322 * typec_altmode2port - Alternate Mode to USB Type-C port 323 * @alt: The Alternate Mode 324 * 325 * Returns handle to the port that a cable plug or partner with @alt is 326 * connected to. 327 */ 328struct typec_port *typec_altmode2port(struct typec_altmode *alt) 329{ 330 if (is_typec_plug(alt->dev.parent)) 331 return to_typec_port(alt->dev.parent->parent->parent); 332 if (is_typec_partner(alt->dev.parent)) 333 return to_typec_port(alt->dev.parent->parent); 334 if (is_typec_port(alt->dev.parent)) 335 return to_typec_port(alt->dev.parent); 336 337 return NULL; 338} 339EXPORT_SYMBOL_GPL(typec_altmode2port); 340 341static ssize_t 342vdo_show(struct device *dev, struct device_attribute *attr, char *buf) 343{ 344 struct typec_altmode *alt = to_typec_altmode(dev); 345 346 return sprintf(buf, "0x%08x\n", alt->vdo); 347} 348static DEVICE_ATTR_RO(vdo); 349 350static ssize_t 351description_show(struct device *dev, struct device_attribute *attr, char *buf) 352{ 353 struct typec_altmode *alt = to_typec_altmode(dev); 354 355 return sprintf(buf, "%s\n", alt->desc ? alt->desc : ""); 356} 357static DEVICE_ATTR_RO(description); 358 359static ssize_t 360active_show(struct device *dev, struct device_attribute *attr, char *buf) 361{ 362 struct typec_altmode *alt = to_typec_altmode(dev); 363 364 return sprintf(buf, "%s\n", alt->active ? "yes" : "no"); 365} 366 367static ssize_t active_store(struct device *dev, struct device_attribute *attr, 368 const char *buf, size_t size) 369{ 370 struct typec_altmode *adev = to_typec_altmode(dev); 371 struct altmode *altmode = to_altmode(adev); 372 bool enter; 373 int ret; 374 375 ret = kstrtobool(buf, &enter); 376 if (ret) 377 return ret; 378 379 if (adev->active == enter) 380 return size; 381 382 if (is_typec_port(adev->dev.parent)) { 383 typec_altmode_update_active(adev, enter); 384 385 /* Make sure that the partner exits the mode before disabling */ 386 if (altmode->partner && !enter && altmode->partner->adev.active) 387 typec_altmode_exit(&altmode->partner->adev); 388 } else if (altmode->partner) { 389 if (enter && !altmode->partner->adev.active) { 390 dev_warn(dev, "port has the mode disabled\n"); 391 return -EPERM; 392 } 393 } 394 395 /* Note: If there is no driver, the mode will not be entered */ 396 if (adev->ops && adev->ops->activate) { 397 ret = adev->ops->activate(adev, enter); 398 if (ret) 399 return ret; 400 } 401 402 return size; 403} 404static DEVICE_ATTR_RW(active); 405 406static ssize_t 407supported_roles_show(struct device *dev, struct device_attribute *attr, 408 char *buf) 409{ 410 struct altmode *alt = to_altmode(to_typec_altmode(dev)); 411 ssize_t ret; 412 413 switch (alt->roles) { 414 case TYPEC_PORT_SRC: 415 ret = sprintf(buf, "source\n"); 416 break; 417 case TYPEC_PORT_SNK: 418 ret = sprintf(buf, "sink\n"); 419 break; 420 case TYPEC_PORT_DRP: 421 default: 422 ret = sprintf(buf, "source sink\n"); 423 break; 424 } 425 return ret; 426} 427static DEVICE_ATTR_RO(supported_roles); 428 429static ssize_t 430mode_show(struct device *dev, struct device_attribute *attr, char *buf) 431{ 432 struct typec_altmode *adev = to_typec_altmode(dev); 433 434 return sprintf(buf, "%u\n", adev->mode); 435} 436static DEVICE_ATTR_RO(mode); 437 438static ssize_t 439svid_show(struct device *dev, struct device_attribute *attr, char *buf) 440{ 441 struct typec_altmode *adev = to_typec_altmode(dev); 442 443 return sprintf(buf, "%04x\n", adev->svid); 444} 445static DEVICE_ATTR_RO(svid); 446 447static struct attribute *typec_altmode_attrs[] = { 448 &dev_attr_active.attr, 449 &dev_attr_mode.attr, 450 &dev_attr_svid.attr, 451 &dev_attr_vdo.attr, 452 NULL 453}; 454 455static umode_t typec_altmode_attr_is_visible(struct kobject *kobj, 456 struct attribute *attr, int n) 457{ 458 struct typec_altmode *adev = to_typec_altmode(kobj_to_dev(kobj)); 459 460 if (attr == &dev_attr_active.attr) 461 if (!adev->ops || !adev->ops->activate) 462 return 0444; 463 464 return attr->mode; 465} 466 467static const struct attribute_group typec_altmode_group = { 468 .is_visible = typec_altmode_attr_is_visible, 469 .attrs = typec_altmode_attrs, 470}; 471 472static const struct attribute_group *typec_altmode_groups[] = { 473 &typec_altmode_group, 474 NULL 475}; 476 477/** 478 * typec_altmode_set_ops - Set ops for altmode 479 * @adev: Handle to the alternate mode 480 * @ops: Ops for the alternate mode 481 * 482 * After setting ops, attribute visiblity needs to be refreshed if the alternate 483 * mode can be activated. 484 */ 485void typec_altmode_set_ops(struct typec_altmode *adev, 486 const struct typec_altmode_ops *ops) 487{ 488 adev->ops = ops; 489 sysfs_update_group(&adev->dev.kobj, &typec_altmode_group); 490} 491EXPORT_SYMBOL_GPL(typec_altmode_set_ops); 492 493static int altmode_id_get(struct device *dev) 494{ 495 struct ida *ids; 496 497 if (is_typec_partner(dev)) 498 ids = &to_typec_partner(dev)->mode_ids; 499 else if (is_typec_plug(dev)) 500 ids = &to_typec_plug(dev)->mode_ids; 501 else 502 ids = &to_typec_port(dev)->mode_ids; 503 504 return ida_alloc(ids, GFP_KERNEL); 505} 506 507static void altmode_id_remove(struct device *dev, int id) 508{ 509 struct ida *ids; 510 511 if (is_typec_partner(dev)) 512 ids = &to_typec_partner(dev)->mode_ids; 513 else if (is_typec_plug(dev)) 514 ids = &to_typec_plug(dev)->mode_ids; 515 else 516 ids = &to_typec_port(dev)->mode_ids; 517 518 ida_free(ids, id); 519} 520 521static void typec_altmode_release(struct device *dev) 522{ 523 struct altmode *alt = to_altmode(to_typec_altmode(dev)); 524 525 if (!is_typec_port(dev->parent)) 526 typec_altmode_put_partner(alt); 527 528 altmode_id_remove(alt->adev.dev.parent, alt->id); 529 put_device(alt->adev.dev.parent); 530 kfree(alt); 531} 532 533const struct device_type typec_altmode_dev_type = { 534 .name = "typec_alternate_mode", 535 .groups = typec_altmode_groups, 536 .release = typec_altmode_release, 537}; 538 539static struct typec_altmode * 540typec_register_altmode(struct device *parent, 541 const struct typec_altmode_desc *desc) 542{ 543 unsigned int id = altmode_id_get(parent); 544 bool is_port = is_typec_port(parent); 545 struct altmode *alt; 546 int ret; 547 548 alt = kzalloc(sizeof(*alt), GFP_KERNEL); 549 if (!alt) { 550 altmode_id_remove(parent, id); 551 return ERR_PTR(-ENOMEM); 552 } 553 554 alt->adev.svid = desc->svid; 555 alt->adev.mode = desc->mode; 556 alt->adev.vdo = desc->vdo; 557 alt->roles = desc->roles; 558 alt->id = id; 559 560 alt->attrs[0] = &dev_attr_vdo.attr; 561 alt->attrs[1] = &dev_attr_description.attr; 562 alt->attrs[2] = &dev_attr_active.attr; 563 564 if (is_port) { 565 alt->attrs[3] = &dev_attr_supported_roles.attr; 566 alt->adev.active = true; /* Enabled by default */ 567 } 568 569 sprintf(alt->group_name, "mode%d", desc->mode); 570 alt->group.name = alt->group_name; 571 alt->group.attrs = alt->attrs; 572 alt->groups[0] = &alt->group; 573 574 alt->adev.dev.parent = parent; 575 alt->adev.dev.groups = alt->groups; 576 alt->adev.dev.type = &typec_altmode_dev_type; 577 dev_set_name(&alt->adev.dev, "%s.%u", dev_name(parent), id); 578 579 get_device(alt->adev.dev.parent); 580 581 /* Link partners and plugs with the ports */ 582 if (!is_port) 583 typec_altmode_set_partner(alt); 584 585 /* The partners are bind to drivers */ 586 if (is_typec_partner(parent)) 587 alt->adev.dev.bus = &typec_bus; 588 589 /* Plug alt modes need a class to generate udev events. */ 590 if (is_typec_plug(parent)) 591 alt->adev.dev.class = &typec_class; 592 593 ret = device_register(&alt->adev.dev); 594 if (ret) { 595 dev_err(parent, "failed to register alternate mode (%d)\n", 596 ret); 597 put_device(&alt->adev.dev); 598 return ERR_PTR(ret); 599 } 600 601 return &alt->adev; 602} 603 604/** 605 * typec_unregister_altmode - Unregister Alternate Mode 606 * @adev: The alternate mode to be unregistered 607 * 608 * Unregister device created with typec_partner_register_altmode(), 609 * typec_plug_register_altmode() or typec_port_register_altmode(). 610 */ 611void typec_unregister_altmode(struct typec_altmode *adev) 612{ 613 if (IS_ERR_OR_NULL(adev)) 614 return; 615 typec_retimer_put(to_altmode(adev)->retimer); 616 typec_mux_put(to_altmode(adev)->mux); 617 device_unregister(&adev->dev); 618} 619EXPORT_SYMBOL_GPL(typec_unregister_altmode); 620 621/* ------------------------------------------------------------------------- */ 622/* Type-C Partners */ 623 624/** 625 * typec_partner_set_usb_mode - Assign active USB Mode for the partner 626 * @partner: USB Type-C partner 627 * @mode: USB Mode (USB2, USB3 or USB4) 628 * 629 * The port drivers can use this function to assign the active USB Mode to 630 * @partner. The USB Mode can change for example due to Data Reset. 631 */ 632void typec_partner_set_usb_mode(struct typec_partner *partner, enum usb_mode mode) 633{ 634 if (!partner || partner->usb_mode == mode) 635 return; 636 637 partner->usb_capability |= BIT(mode - 1); 638 partner->usb_mode = mode; 639 sysfs_notify(&partner->dev.kobj, NULL, "usb_mode"); 640} 641EXPORT_SYMBOL_GPL(typec_partner_set_usb_mode); 642 643static ssize_t 644usb_mode_show(struct device *dev, struct device_attribute *attr, char *buf) 645{ 646 struct typec_partner *partner = to_typec_partner(dev); 647 int len = 0; 648 int i; 649 650 for (i = USB_MODE_USB2; i < USB_MODE_USB4 + 1; i++) { 651 if (!(BIT(i - 1) & partner->usb_capability)) 652 continue; 653 654 if (i == partner->usb_mode) 655 len += sysfs_emit_at(buf, len, "[%s] ", usb_modes[i]); 656 else 657 len += sysfs_emit_at(buf, len, "%s ", usb_modes[i]); 658 } 659 660 sysfs_emit_at(buf, len - 1, "\n"); 661 662 return len; 663} 664 665static ssize_t usb_mode_store(struct device *dev, struct device_attribute *attr, 666 const char *buf, size_t size) 667{ 668 struct typec_partner *partner = to_typec_partner(dev); 669 struct typec_port *port = to_typec_port(dev->parent); 670 int mode; 671 int ret; 672 673 if (!port->ops || !port->ops->enter_usb_mode) 674 return -EOPNOTSUPP; 675 676 mode = sysfs_match_string(usb_modes, buf); 677 if (mode < 0) 678 return mode; 679 680 if (mode == partner->usb_mode) 681 return size; 682 683 ret = port->ops->enter_usb_mode(port, mode); 684 if (ret) 685 return ret; 686 687 typec_partner_set_usb_mode(partner, mode); 688 689 return size; 690} 691static DEVICE_ATTR_RW(usb_mode); 692 693static ssize_t accessory_mode_show(struct device *dev, 694 struct device_attribute *attr, 695 char *buf) 696{ 697 struct typec_partner *p = to_typec_partner(dev); 698 699 return sprintf(buf, "%s\n", typec_accessory_modes[p->accessory]); 700} 701static DEVICE_ATTR_RO(accessory_mode); 702 703static ssize_t supports_usb_power_delivery_show(struct device *dev, 704 struct device_attribute *attr, 705 char *buf) 706{ 707 struct typec_partner *p = to_typec_partner(dev); 708 709 return sprintf(buf, "%s\n", p->usb_pd ? "yes" : "no"); 710} 711static DEVICE_ATTR_RO(supports_usb_power_delivery); 712 713static ssize_t number_of_alternate_modes_show(struct device *dev, struct device_attribute *attr, 714 char *buf) 715{ 716 struct typec_partner *partner; 717 struct typec_plug *plug; 718 int num_altmodes; 719 720 if (is_typec_partner(dev)) { 721 partner = to_typec_partner(dev); 722 num_altmodes = partner->num_altmodes; 723 } else if (is_typec_plug(dev)) { 724 plug = to_typec_plug(dev); 725 num_altmodes = plug->num_altmodes; 726 } else { 727 return 0; 728 } 729 730 return sysfs_emit(buf, "%d\n", num_altmodes); 731} 732static DEVICE_ATTR_RO(number_of_alternate_modes); 733 734static struct attribute *typec_partner_attrs[] = { 735 &dev_attr_accessory_mode.attr, 736 &dev_attr_supports_usb_power_delivery.attr, 737 &dev_attr_number_of_alternate_modes.attr, 738 &dev_attr_type.attr, 739 &dev_attr_usb_mode.attr, 740 &dev_attr_usb_power_delivery_revision.attr, 741 NULL 742}; 743 744static umode_t typec_partner_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) 745{ 746 struct typec_partner *partner = to_typec_partner(kobj_to_dev(kobj)); 747 struct typec_port *port = to_typec_port(partner->dev.parent); 748 749 if (attr == &dev_attr_usb_mode.attr) { 750 if (!partner->usb_capability) 751 return 0; 752 if (!port->ops || !port->ops->enter_usb_mode) 753 return 0444; 754 } 755 756 if (attr == &dev_attr_number_of_alternate_modes.attr) { 757 if (partner->num_altmodes < 0) 758 return 0; 759 } 760 761 if (attr == &dev_attr_type.attr) 762 if (!get_pd_product_type(kobj_to_dev(kobj))) 763 return 0; 764 765 return attr->mode; 766} 767 768static const struct attribute_group typec_partner_group = { 769 .is_visible = typec_partner_attr_is_visible, 770 .attrs = typec_partner_attrs 771}; 772 773static const struct attribute_group *typec_partner_groups[] = { 774 &typec_partner_group, 775 NULL 776}; 777 778static void typec_partner_release(struct device *dev) 779{ 780 struct typec_partner *partner = to_typec_partner(dev); 781 782 ida_destroy(&partner->mode_ids); 783 kfree(partner); 784} 785 786const struct device_type typec_partner_dev_type = { 787 .name = "typec_partner", 788 .groups = typec_partner_groups, 789 .release = typec_partner_release, 790}; 791 792static void typec_partner_link_device(struct typec_partner *partner, struct device *dev) 793{ 794 int ret; 795 796 ret = sysfs_create_link(&dev->kobj, &partner->dev.kobj, "typec"); 797 if (ret) 798 return; 799 800 ret = sysfs_create_link(&partner->dev.kobj, &dev->kobj, dev_name(dev)); 801 if (ret) { 802 sysfs_remove_link(&dev->kobj, "typec"); 803 return; 804 } 805 806 if (partner->attach) 807 partner->attach(partner, dev); 808} 809 810static void typec_partner_unlink_device(struct typec_partner *partner, struct device *dev) 811{ 812 sysfs_remove_link(&partner->dev.kobj, dev_name(dev)); 813 sysfs_remove_link(&dev->kobj, "typec"); 814 815 if (partner->deattach) 816 partner->deattach(partner, dev); 817} 818 819/** 820 * typec_partner_set_identity - Report result from Discover Identity command 821 * @partner: The partner updated identity values 822 * 823 * This routine is used to report that the result of Discover Identity USB power 824 * delivery command has become available. 825 */ 826int typec_partner_set_identity(struct typec_partner *partner) 827{ 828 u8 usb_capability = partner->usb_capability; 829 struct device *dev = &partner->dev; 830 struct usb_pd_identity *id; 831 832 id = get_pd_identity(dev); 833 if (!id) 834 return -EINVAL; 835 836 if (to_typec_port(dev->parent)->data_role == TYPEC_HOST) { 837 u32 devcap = PD_VDO_UFP_DEVCAP(id->vdo[0]); 838 839 if (devcap & (DEV_USB2_CAPABLE | DEV_USB2_BILLBOARD)) 840 usb_capability |= USB_CAPABILITY_USB2; 841 if (devcap & DEV_USB3_CAPABLE) 842 usb_capability |= USB_CAPABILITY_USB3; 843 if (devcap & DEV_USB4_CAPABLE) 844 usb_capability |= USB_CAPABILITY_USB4; 845 } else { 846 usb_capability = PD_VDO_DFP_HOSTCAP(id->vdo[0]); 847 } 848 849 if (partner->usb_capability != usb_capability) { 850 partner->usb_capability = usb_capability; 851 sysfs_notify(&dev->kobj, NULL, "usb_mode"); 852 } 853 854 typec_report_identity(dev); 855 return 0; 856} 857EXPORT_SYMBOL_GPL(typec_partner_set_identity); 858 859/** 860 * typec_partner_set_pd_revision - Set the PD revision supported by the partner 861 * @partner: The partner to be updated. 862 * @pd_revision: USB Power Delivery Specification Revision supported by partner 863 * 864 * This routine is used to report that the PD revision of the port partner has 865 * become available. 866 */ 867void typec_partner_set_pd_revision(struct typec_partner *partner, u16 pd_revision) 868{ 869 if (partner->pd_revision == pd_revision) 870 return; 871 872 partner->pd_revision = pd_revision; 873 sysfs_notify(&partner->dev.kobj, NULL, "usb_power_delivery_revision"); 874 if (pd_revision != 0 && !partner->usb_pd) { 875 partner->usb_pd = 1; 876 sysfs_notify(&partner->dev.kobj, NULL, 877 "supports_usb_power_delivery"); 878 } 879 kobject_uevent(&partner->dev.kobj, KOBJ_CHANGE); 880} 881EXPORT_SYMBOL_GPL(typec_partner_set_pd_revision); 882 883/** 884 * typec_partner_set_usb_power_delivery - Declare USB Power Delivery Contract. 885 * @partner: The partner device. 886 * @pd: The USB PD instance. 887 * 888 * This routine can be used to declare USB Power Delivery Contract with @partner 889 * by linking @partner to @pd which contains the objects that were used during the 890 * negotiation of the contract. 891 * 892 * If @pd is NULL, the link is removed and the contract with @partner has ended. 893 */ 894int typec_partner_set_usb_power_delivery(struct typec_partner *partner, 895 struct usb_power_delivery *pd) 896{ 897 int ret; 898 899 if (IS_ERR_OR_NULL(partner) || partner->pd == pd) 900 return 0; 901 902 if (pd) { 903 ret = usb_power_delivery_link_device(pd, &partner->dev); 904 if (ret) 905 return ret; 906 } else { 907 usb_power_delivery_unlink_device(partner->pd, &partner->dev); 908 } 909 910 partner->pd = pd; 911 912 return 0; 913} 914EXPORT_SYMBOL_GPL(typec_partner_set_usb_power_delivery); 915 916/** 917 * typec_partner_set_num_altmodes - Set the number of available partner altmodes 918 * @partner: The partner to be updated. 919 * @num_altmodes: The number of altmodes we want to specify as available. 920 * 921 * This routine is used to report the number of alternate modes supported by the 922 * partner. This value is *not* enforced in alternate mode registration routines. 923 * 924 * @partner.num_altmodes is set to -1 on partner registration, denoting that 925 * a valid value has not been set for it yet. 926 * 927 * Returns 0 on success or negative error number on failure. 928 */ 929int typec_partner_set_num_altmodes(struct typec_partner *partner, int num_altmodes) 930{ 931 int ret; 932 933 if (num_altmodes < 0) 934 return -EINVAL; 935 936 partner->num_altmodes = num_altmodes; 937 ret = sysfs_update_group(&partner->dev.kobj, &typec_partner_group); 938 if (ret < 0) 939 return ret; 940 941 sysfs_notify(&partner->dev.kobj, NULL, "number_of_alternate_modes"); 942 kobject_uevent(&partner->dev.kobj, KOBJ_CHANGE); 943 944 return 0; 945} 946EXPORT_SYMBOL_GPL(typec_partner_set_num_altmodes); 947 948/** 949 * typec_partner_register_altmode - Register USB Type-C Partner Alternate Mode 950 * @partner: USB Type-C Partner that supports the alternate mode 951 * @desc: Description of the alternate mode 952 * 953 * This routine is used to register each alternate mode individually that 954 * @partner has listed in response to Discover SVIDs command. The modes for a 955 * SVID listed in response to Discover Modes command need to be listed in an 956 * array in @desc. 957 * 958 * Returns handle to the alternate mode on success or ERR_PTR on failure. 959 */ 960struct typec_altmode * 961typec_partner_register_altmode(struct typec_partner *partner, 962 const struct typec_altmode_desc *desc) 963{ 964 return typec_register_altmode(&partner->dev, desc); 965} 966EXPORT_SYMBOL_GPL(typec_partner_register_altmode); 967 968/** 969 * typec_partner_set_svdm_version - Set negotiated Structured VDM (SVDM) Version 970 * @partner: USB Type-C Partner that supports SVDM 971 * @svdm_version: Negotiated SVDM Version 972 * 973 * This routine is used to save the negotiated SVDM Version. 974 */ 975void typec_partner_set_svdm_version(struct typec_partner *partner, 976 enum usb_pd_svdm_ver svdm_version) 977{ 978 partner->svdm_version = svdm_version; 979} 980EXPORT_SYMBOL_GPL(typec_partner_set_svdm_version); 981 982/** 983 * typec_partner_usb_power_delivery_register - Register Type-C partner USB Power Delivery Support 984 * @partner: Type-C partner device. 985 * @desc: Description of the USB PD contract. 986 * 987 * This routine is a wrapper around usb_power_delivery_register(). It registers 988 * USB Power Delivery Capabilities for a Type-C partner device. Specifically, 989 * it sets the Type-C partner device as a parent for the resulting USB Power Delivery object. 990 * 991 * Returns handle to struct usb_power_delivery or ERR_PTR. 992 */ 993struct usb_power_delivery * 994typec_partner_usb_power_delivery_register(struct typec_partner *partner, 995 struct usb_power_delivery_desc *desc) 996{ 997 return usb_power_delivery_register(&partner->dev, desc); 998} 999EXPORT_SYMBOL_GPL(typec_partner_usb_power_delivery_register); 1000 1001/** 1002 * typec_register_partner - Register a USB Type-C Partner 1003 * @port: The USB Type-C Port the partner is connected to 1004 * @desc: Description of the partner 1005 * 1006 * Registers a device for USB Type-C Partner described in @desc. 1007 * 1008 * Returns handle to the partner on success or ERR_PTR on failure. 1009 */ 1010struct typec_partner *typec_register_partner(struct typec_port *port, 1011 struct typec_partner_desc *desc) 1012{ 1013 struct typec_partner *partner; 1014 int ret; 1015 1016 partner = kzalloc(sizeof(*partner), GFP_KERNEL); 1017 if (!partner) 1018 return ERR_PTR(-ENOMEM); 1019 1020 ida_init(&partner->mode_ids); 1021 partner->usb_pd = desc->usb_pd; 1022 partner->accessory = desc->accessory; 1023 partner->num_altmodes = -1; 1024 partner->usb_capability = desc->usb_capability; 1025 partner->pd_revision = desc->pd_revision; 1026 partner->svdm_version = port->cap->svdm_version; 1027 partner->attach = desc->attach; 1028 partner->deattach = desc->deattach; 1029 1030 if (desc->identity) { 1031 /* 1032 * Creating directory for the identity only if the driver is 1033 * able to provide data to it. 1034 */ 1035 partner->dev.groups = usb_pd_id_groups; 1036 partner->identity = desc->identity; 1037 } 1038 1039 partner->dev.class = &typec_class; 1040 partner->dev.parent = &port->dev; 1041 partner->dev.type = &typec_partner_dev_type; 1042 dev_set_name(&partner->dev, "%s-partner", dev_name(&port->dev)); 1043 1044 if (port->usb2_dev) { 1045 partner->usb_capability |= USB_CAPABILITY_USB2; 1046 partner->usb_mode = USB_MODE_USB2; 1047 } 1048 if (port->usb3_dev) { 1049 partner->usb_capability |= USB_CAPABILITY_USB2 | USB_CAPABILITY_USB3; 1050 partner->usb_mode = USB_MODE_USB3; 1051 } 1052 1053 ret = device_register(&partner->dev); 1054 if (ret) { 1055 dev_err(&port->dev, "failed to register partner (%d)\n", ret); 1056 put_device(&partner->dev); 1057 return ERR_PTR(ret); 1058 } 1059 1060 if (port->usb2_dev) 1061 typec_partner_link_device(partner, port->usb2_dev); 1062 if (port->usb3_dev) 1063 typec_partner_link_device(partner, port->usb3_dev); 1064 1065 return partner; 1066} 1067EXPORT_SYMBOL_GPL(typec_register_partner); 1068 1069/** 1070 * typec_unregister_partner - Unregister a USB Type-C Partner 1071 * @partner: The partner to be unregistered 1072 * 1073 * Unregister device created with typec_register_partner(). 1074 */ 1075void typec_unregister_partner(struct typec_partner *partner) 1076{ 1077 struct typec_port *port; 1078 1079 if (IS_ERR_OR_NULL(partner)) 1080 return; 1081 1082 port = to_typec_port(partner->dev.parent); 1083 1084 if (port->usb2_dev) 1085 typec_partner_unlink_device(partner, port->usb2_dev); 1086 if (port->usb3_dev) 1087 typec_partner_unlink_device(partner, port->usb3_dev); 1088 1089 device_unregister(&partner->dev); 1090} 1091EXPORT_SYMBOL_GPL(typec_unregister_partner); 1092 1093/* ------------------------------------------------------------------------- */ 1094/* Type-C Cable Plugs */ 1095 1096static void typec_plug_release(struct device *dev) 1097{ 1098 struct typec_plug *plug = to_typec_plug(dev); 1099 1100 ida_destroy(&plug->mode_ids); 1101 kfree(plug); 1102} 1103 1104static struct attribute *typec_plug_attrs[] = { 1105 &dev_attr_number_of_alternate_modes.attr, 1106 NULL 1107}; 1108 1109static umode_t typec_plug_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) 1110{ 1111 struct typec_plug *plug = to_typec_plug(kobj_to_dev(kobj)); 1112 1113 if (attr == &dev_attr_number_of_alternate_modes.attr) { 1114 if (plug->num_altmodes < 0) 1115 return 0; 1116 } 1117 1118 return attr->mode; 1119} 1120 1121static const struct attribute_group typec_plug_group = { 1122 .is_visible = typec_plug_attr_is_visible, 1123 .attrs = typec_plug_attrs 1124}; 1125 1126static const struct attribute_group *typec_plug_groups[] = { 1127 &typec_plug_group, 1128 NULL 1129}; 1130 1131const struct device_type typec_plug_dev_type = { 1132 .name = "typec_plug", 1133 .groups = typec_plug_groups, 1134 .release = typec_plug_release, 1135}; 1136 1137/** 1138 * typec_plug_set_num_altmodes - Set the number of available plug altmodes 1139 * @plug: The plug to be updated. 1140 * @num_altmodes: The number of altmodes we want to specify as available. 1141 * 1142 * This routine is used to report the number of alternate modes supported by the 1143 * plug. This value is *not* enforced in alternate mode registration routines. 1144 * 1145 * @plug.num_altmodes is set to -1 on plug registration, denoting that 1146 * a valid value has not been set for it yet. 1147 * 1148 * Returns 0 on success or negative error number on failure. 1149 */ 1150int typec_plug_set_num_altmodes(struct typec_plug *plug, int num_altmodes) 1151{ 1152 int ret; 1153 1154 if (num_altmodes < 0) 1155 return -EINVAL; 1156 1157 plug->num_altmodes = num_altmodes; 1158 ret = sysfs_update_group(&plug->dev.kobj, &typec_plug_group); 1159 if (ret < 0) 1160 return ret; 1161 1162 sysfs_notify(&plug->dev.kobj, NULL, "number_of_alternate_modes"); 1163 kobject_uevent(&plug->dev.kobj, KOBJ_CHANGE); 1164 1165 return 0; 1166} 1167EXPORT_SYMBOL_GPL(typec_plug_set_num_altmodes); 1168 1169/** 1170 * typec_plug_register_altmode - Register USB Type-C Cable Plug Alternate Mode 1171 * @plug: USB Type-C Cable Plug that supports the alternate mode 1172 * @desc: Description of the alternate mode 1173 * 1174 * This routine is used to register each alternate mode individually that @plug 1175 * has listed in response to Discover SVIDs command. The modes for a SVID that 1176 * the plug lists in response to Discover Modes command need to be listed in an 1177 * array in @desc. 1178 * 1179 * Returns handle to the alternate mode on success or ERR_PTR on failure. 1180 */ 1181struct typec_altmode * 1182typec_plug_register_altmode(struct typec_plug *plug, 1183 const struct typec_altmode_desc *desc) 1184{ 1185 return typec_register_altmode(&plug->dev, desc); 1186} 1187EXPORT_SYMBOL_GPL(typec_plug_register_altmode); 1188 1189/** 1190 * typec_register_plug - Register a USB Type-C Cable Plug 1191 * @cable: USB Type-C Cable with the plug 1192 * @desc: Description of the cable plug 1193 * 1194 * Registers a device for USB Type-C Cable Plug described in @desc. A USB Type-C 1195 * Cable Plug represents a plug with electronics in it that can response to USB 1196 * Power Delivery SOP Prime or SOP Double Prime packages. 1197 * 1198 * Returns handle to the cable plug on success or ERR_PTR on failure. 1199 */ 1200struct typec_plug *typec_register_plug(struct typec_cable *cable, 1201 struct typec_plug_desc *desc) 1202{ 1203 struct typec_plug *plug; 1204 char name[8]; 1205 int ret; 1206 1207 plug = kzalloc(sizeof(*plug), GFP_KERNEL); 1208 if (!plug) 1209 return ERR_PTR(-ENOMEM); 1210 1211 sprintf(name, "plug%d", desc->index); 1212 1213 ida_init(&plug->mode_ids); 1214 plug->num_altmodes = -1; 1215 plug->index = desc->index; 1216 plug->dev.class = &typec_class; 1217 plug->dev.parent = &cable->dev; 1218 plug->dev.type = &typec_plug_dev_type; 1219 dev_set_name(&plug->dev, "%s-%s", dev_name(cable->dev.parent), name); 1220 1221 ret = device_register(&plug->dev); 1222 if (ret) { 1223 dev_err(&cable->dev, "failed to register plug (%d)\n", ret); 1224 put_device(&plug->dev); 1225 return ERR_PTR(ret); 1226 } 1227 1228 return plug; 1229} 1230EXPORT_SYMBOL_GPL(typec_register_plug); 1231 1232/** 1233 * typec_unregister_plug - Unregister a USB Type-C Cable Plug 1234 * @plug: The cable plug to be unregistered 1235 * 1236 * Unregister device created with typec_register_plug(). 1237 */ 1238void typec_unregister_plug(struct typec_plug *plug) 1239{ 1240 if (!IS_ERR_OR_NULL(plug)) 1241 device_unregister(&plug->dev); 1242} 1243EXPORT_SYMBOL_GPL(typec_unregister_plug); 1244 1245/* Type-C Cables */ 1246 1247static const char * const typec_plug_types[] = { 1248 [USB_PLUG_NONE] = "unknown", 1249 [USB_PLUG_TYPE_A] = "type-a", 1250 [USB_PLUG_TYPE_B] = "type-b", 1251 [USB_PLUG_TYPE_C] = "type-c", 1252 [USB_PLUG_CAPTIVE] = "captive", 1253}; 1254 1255static ssize_t plug_type_show(struct device *dev, 1256 struct device_attribute *attr, char *buf) 1257{ 1258 struct typec_cable *cable = to_typec_cable(dev); 1259 1260 return sprintf(buf, "%s\n", typec_plug_types[cable->type]); 1261} 1262static DEVICE_ATTR_RO(plug_type); 1263 1264static struct attribute *typec_cable_attrs[] = { 1265 &dev_attr_type.attr, 1266 &dev_attr_plug_type.attr, 1267 &dev_attr_usb_power_delivery_revision.attr, 1268 NULL 1269}; 1270ATTRIBUTE_GROUPS(typec_cable); 1271 1272static void typec_cable_release(struct device *dev) 1273{ 1274 struct typec_cable *cable = to_typec_cable(dev); 1275 1276 kfree(cable); 1277} 1278 1279const struct device_type typec_cable_dev_type = { 1280 .name = "typec_cable", 1281 .groups = typec_cable_groups, 1282 .release = typec_cable_release, 1283}; 1284 1285static int cable_match(struct device *dev, void *data) 1286{ 1287 return is_typec_cable(dev); 1288} 1289 1290/** 1291 * typec_cable_get - Get a reference to the USB Type-C cable 1292 * @port: The USB Type-C Port the cable is connected to 1293 * 1294 * The caller must decrement the reference count with typec_cable_put() after 1295 * use. 1296 */ 1297struct typec_cable *typec_cable_get(struct typec_port *port) 1298{ 1299 struct device *dev; 1300 1301 dev = device_find_child(&port->dev, NULL, cable_match); 1302 if (!dev) 1303 return NULL; 1304 1305 return to_typec_cable(dev); 1306} 1307EXPORT_SYMBOL_GPL(typec_cable_get); 1308 1309/** 1310 * typec_cable_put - Decrement the reference count on USB Type-C cable 1311 * @cable: The USB Type-C cable 1312 */ 1313void typec_cable_put(struct typec_cable *cable) 1314{ 1315 put_device(&cable->dev); 1316} 1317EXPORT_SYMBOL_GPL(typec_cable_put); 1318 1319/** 1320 * typec_cable_is_active - Check is the USB Type-C cable active or passive 1321 * @cable: The USB Type-C Cable 1322 * 1323 * Return 1 if the cable is active or 0 if it's passive. 1324 */ 1325int typec_cable_is_active(struct typec_cable *cable) 1326{ 1327 return cable->active; 1328} 1329EXPORT_SYMBOL_GPL(typec_cable_is_active); 1330 1331/** 1332 * typec_cable_set_identity - Report result from Discover Identity command 1333 * @cable: The cable updated identity values 1334 * 1335 * This routine is used to report that the result of Discover Identity USB power 1336 * delivery command has become available. 1337 */ 1338int typec_cable_set_identity(struct typec_cable *cable) 1339{ 1340 if (!cable->identity) 1341 return -EINVAL; 1342 1343 typec_report_identity(&cable->dev); 1344 return 0; 1345} 1346EXPORT_SYMBOL_GPL(typec_cable_set_identity); 1347 1348/** 1349 * typec_register_cable - Register a USB Type-C Cable 1350 * @port: The USB Type-C Port the cable is connected to 1351 * @desc: Description of the cable 1352 * 1353 * Registers a device for USB Type-C Cable described in @desc. The cable will be 1354 * parent for the optional cable plug devises. 1355 * 1356 * Returns handle to the cable on success or ERR_PTR on failure. 1357 */ 1358struct typec_cable *typec_register_cable(struct typec_port *port, 1359 struct typec_cable_desc *desc) 1360{ 1361 struct typec_cable *cable; 1362 int ret; 1363 1364 cable = kzalloc(sizeof(*cable), GFP_KERNEL); 1365 if (!cable) 1366 return ERR_PTR(-ENOMEM); 1367 1368 cable->type = desc->type; 1369 cable->active = desc->active; 1370 cable->pd_revision = desc->pd_revision; 1371 1372 if (desc->identity) { 1373 /* 1374 * Creating directory for the identity only if the driver is 1375 * able to provide data to it. 1376 */ 1377 cable->dev.groups = usb_pd_id_groups; 1378 cable->identity = desc->identity; 1379 } 1380 1381 cable->dev.class = &typec_class; 1382 cable->dev.parent = &port->dev; 1383 cable->dev.type = &typec_cable_dev_type; 1384 dev_set_name(&cable->dev, "%s-cable", dev_name(&port->dev)); 1385 1386 ret = device_register(&cable->dev); 1387 if (ret) { 1388 dev_err(&port->dev, "failed to register cable (%d)\n", ret); 1389 put_device(&cable->dev); 1390 return ERR_PTR(ret); 1391 } 1392 1393 return cable; 1394} 1395EXPORT_SYMBOL_GPL(typec_register_cable); 1396 1397/** 1398 * typec_unregister_cable - Unregister a USB Type-C Cable 1399 * @cable: The cable to be unregistered 1400 * 1401 * Unregister device created with typec_register_cable(). 1402 */ 1403void typec_unregister_cable(struct typec_cable *cable) 1404{ 1405 if (!IS_ERR_OR_NULL(cable)) 1406 device_unregister(&cable->dev); 1407} 1408EXPORT_SYMBOL_GPL(typec_unregister_cable); 1409 1410/* ------------------------------------------------------------------------- */ 1411/* USB Type-C ports */ 1412 1413/** 1414 * typec_port_set_usb_mode - Set the operational USB mode for the port 1415 * @port: USB Type-C port 1416 * @mode: USB Mode (USB2, USB3 or USB4) 1417 * 1418 * @mode will be used with the next Enter_USB message. Existing connections are 1419 * not affected. 1420 */ 1421void typec_port_set_usb_mode(struct typec_port *port, enum usb_mode mode) 1422{ 1423 port->usb_mode = mode; 1424} 1425EXPORT_SYMBOL_GPL(typec_port_set_usb_mode); 1426 1427static ssize_t 1428usb_capability_show(struct device *dev, struct device_attribute *attr, char *buf) 1429{ 1430 struct typec_port *port = to_typec_port(dev); 1431 int len = 0; 1432 int i; 1433 1434 for (i = USB_MODE_USB2; i < USB_MODE_USB4 + 1; i++) { 1435 if (!(BIT(i - 1) & port->cap->usb_capability)) 1436 continue; 1437 1438 if (i == port->usb_mode) 1439 len += sysfs_emit_at(buf, len, "[%s] ", usb_modes[i]); 1440 else 1441 len += sysfs_emit_at(buf, len, "%s ", usb_modes[i]); 1442 } 1443 1444 sysfs_emit_at(buf, len - 1, "\n"); 1445 1446 return len; 1447} 1448 1449static ssize_t 1450usb_capability_store(struct device *dev, struct device_attribute *attr, 1451 const char *buf, size_t size) 1452{ 1453 struct typec_port *port = to_typec_port(dev); 1454 int ret = 0; 1455 int mode; 1456 1457 if (!port->ops || !port->ops->default_usb_mode_set) 1458 return -EOPNOTSUPP; 1459 1460 mode = sysfs_match_string(usb_modes, buf); 1461 if (mode < 0) 1462 return mode; 1463 1464 ret = port->ops->default_usb_mode_set(port, mode); 1465 if (ret) 1466 return ret; 1467 1468 port->usb_mode = mode; 1469 1470 return size; 1471} 1472static DEVICE_ATTR_RW(usb_capability); 1473 1474/** 1475 * typec_port_set_usb_power_delivery - Assign USB PD for port. 1476 * @port: USB Type-C port. 1477 * @pd: USB PD instance. 1478 * 1479 * This routine can be used to set the USB Power Delivery Capabilities for @port 1480 * that it will advertise to the partner. 1481 * 1482 * If @pd is NULL, the assignment is removed. 1483 */ 1484int typec_port_set_usb_power_delivery(struct typec_port *port, struct usb_power_delivery *pd) 1485{ 1486 int ret; 1487 1488 if (IS_ERR_OR_NULL(port) || port->pd == pd) 1489 return 0; 1490 1491 if (pd) { 1492 ret = usb_power_delivery_link_device(pd, &port->dev); 1493 if (ret) 1494 return ret; 1495 } else { 1496 usb_power_delivery_unlink_device(port->pd, &port->dev); 1497 } 1498 1499 port->pd = pd; 1500 1501 return 0; 1502} 1503EXPORT_SYMBOL_GPL(typec_port_set_usb_power_delivery); 1504 1505static ssize_t select_usb_power_delivery_store(struct device *dev, 1506 struct device_attribute *attr, 1507 const char *buf, size_t size) 1508{ 1509 struct typec_port *port = to_typec_port(dev); 1510 struct usb_power_delivery *pd; 1511 int ret; 1512 1513 if (!port->ops || !port->ops->pd_set) 1514 return -EOPNOTSUPP; 1515 1516 pd = usb_power_delivery_find(buf); 1517 if (!pd) 1518 return -EINVAL; 1519 1520 ret = port->ops->pd_set(port, pd); 1521 if (ret) 1522 return ret; 1523 1524 return size; 1525} 1526 1527static ssize_t select_usb_power_delivery_show(struct device *dev, 1528 struct device_attribute *attr, char *buf) 1529{ 1530 struct typec_port *port = to_typec_port(dev); 1531 struct usb_power_delivery **pds; 1532 int i, ret = 0; 1533 1534 if (!port->ops || !port->ops->pd_get) 1535 return -EOPNOTSUPP; 1536 1537 pds = port->ops->pd_get(port); 1538 if (!pds) 1539 return 0; 1540 1541 for (i = 0; pds[i]; i++) { 1542 if (pds[i] == port->pd) 1543 ret += sysfs_emit_at(buf, ret, "[%s] ", dev_name(&pds[i]->dev)); 1544 else 1545 ret += sysfs_emit_at(buf, ret, "%s ", dev_name(&pds[i]->dev)); 1546 } 1547 1548 buf[ret - 1] = '\n'; 1549 1550 return ret; 1551} 1552static DEVICE_ATTR_RW(select_usb_power_delivery); 1553 1554static struct attribute *port_attrs[] = { 1555 &dev_attr_select_usb_power_delivery.attr, 1556 NULL 1557}; 1558 1559static umode_t port_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) 1560{ 1561 struct typec_port *port = to_typec_port(kobj_to_dev(kobj)); 1562 1563 if (!port->pd || !port->ops || !port->ops->pd_get) 1564 return 0; 1565 if (!port->ops->pd_set) 1566 return 0444; 1567 1568 return attr->mode; 1569} 1570 1571static const struct attribute_group pd_group = { 1572 .is_visible = port_attr_is_visible, 1573 .attrs = port_attrs, 1574}; 1575 1576static const char * const typec_orientations[] = { 1577 [TYPEC_ORIENTATION_NONE] = "unknown", 1578 [TYPEC_ORIENTATION_NORMAL] = "normal", 1579 [TYPEC_ORIENTATION_REVERSE] = "reverse", 1580}; 1581 1582static const char * const typec_roles[] = { 1583 [TYPEC_SINK] = "sink", 1584 [TYPEC_SOURCE] = "source", 1585}; 1586 1587static const char * const typec_data_roles[] = { 1588 [TYPEC_DEVICE] = "device", 1589 [TYPEC_HOST] = "host", 1590}; 1591 1592static const char * const typec_port_power_roles[] = { 1593 [TYPEC_PORT_SRC] = "source", 1594 [TYPEC_PORT_SNK] = "sink", 1595 [TYPEC_PORT_DRP] = "dual", 1596}; 1597 1598static const char * const typec_port_data_roles[] = { 1599 [TYPEC_PORT_DFP] = "host", 1600 [TYPEC_PORT_UFP] = "device", 1601 [TYPEC_PORT_DRD] = "dual", 1602}; 1603 1604static const char * const typec_port_types_drp[] = { 1605 [TYPEC_PORT_SRC] = "dual [source] sink", 1606 [TYPEC_PORT_SNK] = "dual source [sink]", 1607 [TYPEC_PORT_DRP] = "[dual] source sink", 1608}; 1609 1610static ssize_t 1611preferred_role_store(struct device *dev, struct device_attribute *attr, 1612 const char *buf, size_t size) 1613{ 1614 struct typec_port *port = to_typec_port(dev); 1615 int role; 1616 int ret; 1617 1618 if (port->cap->type != TYPEC_PORT_DRP) { 1619 dev_dbg(dev, "Preferred role only supported with DRP ports\n"); 1620 return -EOPNOTSUPP; 1621 } 1622 1623 if (!port->ops || !port->ops->try_role) { 1624 dev_dbg(dev, "Setting preferred role not supported\n"); 1625 return -EOPNOTSUPP; 1626 } 1627 1628 role = sysfs_match_string(typec_roles, buf); 1629 if (role < 0) { 1630 if (sysfs_streq(buf, "none")) 1631 role = TYPEC_NO_PREFERRED_ROLE; 1632 else 1633 return -EINVAL; 1634 } 1635 1636 ret = port->ops->try_role(port, role); 1637 if (ret) 1638 return ret; 1639 1640 port->prefer_role = role; 1641 return size; 1642} 1643 1644static ssize_t 1645preferred_role_show(struct device *dev, struct device_attribute *attr, 1646 char *buf) 1647{ 1648 struct typec_port *port = to_typec_port(dev); 1649 1650 if (port->cap->type != TYPEC_PORT_DRP) 1651 return 0; 1652 1653 if (port->prefer_role < 0) 1654 return 0; 1655 1656 return sprintf(buf, "%s\n", typec_roles[port->prefer_role]); 1657} 1658static DEVICE_ATTR_RW(preferred_role); 1659 1660static ssize_t data_role_store(struct device *dev, 1661 struct device_attribute *attr, 1662 const char *buf, size_t size) 1663{ 1664 struct typec_port *port = to_typec_port(dev); 1665 int ret; 1666 1667 if (!port->ops || !port->ops->dr_set) { 1668 dev_dbg(dev, "data role swapping not supported\n"); 1669 return -EOPNOTSUPP; 1670 } 1671 1672 ret = sysfs_match_string(typec_data_roles, buf); 1673 if (ret < 0) 1674 return ret; 1675 1676 mutex_lock(&port->port_type_lock); 1677 if (port->cap->data != TYPEC_PORT_DRD) { 1678 ret = -EOPNOTSUPP; 1679 goto unlock_and_ret; 1680 } 1681 1682 ret = port->ops->dr_set(port, ret); 1683 if (ret) 1684 goto unlock_and_ret; 1685 1686 ret = size; 1687unlock_and_ret: 1688 mutex_unlock(&port->port_type_lock); 1689 return ret; 1690} 1691 1692static ssize_t data_role_show(struct device *dev, 1693 struct device_attribute *attr, char *buf) 1694{ 1695 struct typec_port *port = to_typec_port(dev); 1696 1697 if (port->cap->data == TYPEC_PORT_DRD) 1698 return sprintf(buf, "%s\n", port->data_role == TYPEC_HOST ? 1699 "[host] device" : "host [device]"); 1700 1701 return sprintf(buf, "[%s]\n", typec_data_roles[port->data_role]); 1702} 1703static DEVICE_ATTR_RW(data_role); 1704 1705static ssize_t power_role_store(struct device *dev, 1706 struct device_attribute *attr, 1707 const char *buf, size_t size) 1708{ 1709 struct typec_port *port = to_typec_port(dev); 1710 int ret; 1711 1712 if (!port->ops || !port->ops->pr_set) { 1713 dev_dbg(dev, "power role swapping not supported\n"); 1714 return -EOPNOTSUPP; 1715 } 1716 1717 if (port->pwr_opmode != TYPEC_PWR_MODE_PD) { 1718 dev_dbg(dev, "partner unable to swap power role\n"); 1719 return -EIO; 1720 } 1721 1722 ret = sysfs_match_string(typec_roles, buf); 1723 if (ret < 0) 1724 return ret; 1725 1726 mutex_lock(&port->port_type_lock); 1727 if (port->port_type != TYPEC_PORT_DRP) { 1728 dev_dbg(dev, "port type fixed at \"%s\"", 1729 typec_port_power_roles[port->port_type]); 1730 ret = -EOPNOTSUPP; 1731 goto unlock_and_ret; 1732 } 1733 1734 ret = port->ops->pr_set(port, ret); 1735 if (ret) 1736 goto unlock_and_ret; 1737 1738 ret = size; 1739unlock_and_ret: 1740 mutex_unlock(&port->port_type_lock); 1741 return ret; 1742} 1743 1744static ssize_t power_role_show(struct device *dev, 1745 struct device_attribute *attr, char *buf) 1746{ 1747 struct typec_port *port = to_typec_port(dev); 1748 1749 if (port->cap->type == TYPEC_PORT_DRP) 1750 return sprintf(buf, "%s\n", port->pwr_role == TYPEC_SOURCE ? 1751 "[source] sink" : "source [sink]"); 1752 1753 return sprintf(buf, "[%s]\n", typec_roles[port->pwr_role]); 1754} 1755static DEVICE_ATTR_RW(power_role); 1756 1757static ssize_t 1758port_type_store(struct device *dev, struct device_attribute *attr, 1759 const char *buf, size_t size) 1760{ 1761 struct typec_port *port = to_typec_port(dev); 1762 int ret; 1763 enum typec_port_type type; 1764 1765 if (port->cap->type != TYPEC_PORT_DRP || 1766 !port->ops || !port->ops->port_type_set) { 1767 dev_dbg(dev, "changing port type not supported\n"); 1768 return -EOPNOTSUPP; 1769 } 1770 1771 ret = sysfs_match_string(typec_port_power_roles, buf); 1772 if (ret < 0) 1773 return ret; 1774 1775 type = ret; 1776 mutex_lock(&port->port_type_lock); 1777 1778 if (port->port_type == type) { 1779 ret = size; 1780 goto unlock_and_ret; 1781 } 1782 1783 ret = port->ops->port_type_set(port, type); 1784 if (ret) 1785 goto unlock_and_ret; 1786 1787 port->port_type = type; 1788 ret = size; 1789 1790unlock_and_ret: 1791 mutex_unlock(&port->port_type_lock); 1792 return ret; 1793} 1794 1795static ssize_t 1796port_type_show(struct device *dev, struct device_attribute *attr, 1797 char *buf) 1798{ 1799 struct typec_port *port = to_typec_port(dev); 1800 1801 if (port->cap->type == TYPEC_PORT_DRP) 1802 return sprintf(buf, "%s\n", 1803 typec_port_types_drp[port->port_type]); 1804 1805 return sprintf(buf, "[%s]\n", typec_port_power_roles[port->cap->type]); 1806} 1807static DEVICE_ATTR_RW(port_type); 1808 1809static const char * const typec_pwr_opmodes[] = { 1810 [TYPEC_PWR_MODE_USB] = "default", 1811 [TYPEC_PWR_MODE_1_5A] = "1.5A", 1812 [TYPEC_PWR_MODE_3_0A] = "3.0A", 1813 [TYPEC_PWR_MODE_PD] = "usb_power_delivery", 1814}; 1815 1816static ssize_t power_operation_mode_show(struct device *dev, 1817 struct device_attribute *attr, 1818 char *buf) 1819{ 1820 struct typec_port *port = to_typec_port(dev); 1821 1822 return sprintf(buf, "%s\n", typec_pwr_opmodes[port->pwr_opmode]); 1823} 1824static DEVICE_ATTR_RO(power_operation_mode); 1825 1826static ssize_t vconn_source_store(struct device *dev, 1827 struct device_attribute *attr, 1828 const char *buf, size_t size) 1829{ 1830 struct typec_port *port = to_typec_port(dev); 1831 bool source; 1832 int ret; 1833 1834 if (!port->cap->pd_revision) { 1835 dev_dbg(dev, "VCONN swap depends on USB Power Delivery\n"); 1836 return -EOPNOTSUPP; 1837 } 1838 1839 if (!port->ops || !port->ops->vconn_set) { 1840 dev_dbg(dev, "VCONN swapping not supported\n"); 1841 return -EOPNOTSUPP; 1842 } 1843 1844 ret = kstrtobool(buf, &source); 1845 if (ret) 1846 return ret; 1847 1848 ret = port->ops->vconn_set(port, (enum typec_role)source); 1849 if (ret) 1850 return ret; 1851 1852 return size; 1853} 1854 1855static ssize_t vconn_source_show(struct device *dev, 1856 struct device_attribute *attr, char *buf) 1857{ 1858 struct typec_port *port = to_typec_port(dev); 1859 1860 return sprintf(buf, "%s\n", 1861 port->vconn_role == TYPEC_SOURCE ? "yes" : "no"); 1862} 1863static DEVICE_ATTR_RW(vconn_source); 1864 1865static ssize_t supported_accessory_modes_show(struct device *dev, 1866 struct device_attribute *attr, 1867 char *buf) 1868{ 1869 struct typec_port *port = to_typec_port(dev); 1870 ssize_t ret = 0; 1871 int i; 1872 1873 for (i = 0; i < ARRAY_SIZE(port->cap->accessory); i++) { 1874 if (port->cap->accessory[i]) 1875 ret += sprintf(buf + ret, "%s ", 1876 typec_accessory_modes[port->cap->accessory[i]]); 1877 } 1878 1879 if (!ret) 1880 return sprintf(buf, "none\n"); 1881 1882 buf[ret - 1] = '\n'; 1883 1884 return ret; 1885} 1886static DEVICE_ATTR_RO(supported_accessory_modes); 1887 1888static ssize_t usb_typec_revision_show(struct device *dev, 1889 struct device_attribute *attr, 1890 char *buf) 1891{ 1892 struct typec_port *port = to_typec_port(dev); 1893 u16 rev = port->cap->revision; 1894 1895 return sprintf(buf, "%d.%d\n", (rev >> 8) & 0xff, (rev >> 4) & 0xf); 1896} 1897static DEVICE_ATTR_RO(usb_typec_revision); 1898 1899static ssize_t usb_power_delivery_revision_show(struct device *dev, 1900 struct device_attribute *attr, 1901 char *buf) 1902{ 1903 u16 rev = 0; 1904 1905 if (is_typec_partner(dev)) { 1906 struct typec_partner *partner = to_typec_partner(dev); 1907 1908 rev = partner->pd_revision; 1909 } else if (is_typec_cable(dev)) { 1910 struct typec_cable *cable = to_typec_cable(dev); 1911 1912 rev = cable->pd_revision; 1913 } else if (is_typec_port(dev)) { 1914 struct typec_port *p = to_typec_port(dev); 1915 1916 rev = p->cap->pd_revision; 1917 } 1918 return sysfs_emit(buf, "%d.%d\n", (rev >> 8) & 0xff, (rev >> 4) & 0xf); 1919} 1920 1921static ssize_t orientation_show(struct device *dev, 1922 struct device_attribute *attr, 1923 char *buf) 1924{ 1925 struct typec_port *port = to_typec_port(dev); 1926 1927 return sprintf(buf, "%s\n", typec_orientations[port->orientation]); 1928} 1929static DEVICE_ATTR_RO(orientation); 1930 1931static struct attribute *typec_attrs[] = { 1932 &dev_attr_data_role.attr, 1933 &dev_attr_power_operation_mode.attr, 1934 &dev_attr_power_role.attr, 1935 &dev_attr_preferred_role.attr, 1936 &dev_attr_supported_accessory_modes.attr, 1937 &dev_attr_usb_power_delivery_revision.attr, 1938 &dev_attr_usb_typec_revision.attr, 1939 &dev_attr_vconn_source.attr, 1940 &dev_attr_port_type.attr, 1941 &dev_attr_orientation.attr, 1942 &dev_attr_usb_capability.attr, 1943 NULL, 1944}; 1945 1946static umode_t typec_attr_is_visible(struct kobject *kobj, 1947 struct attribute *attr, int n) 1948{ 1949 struct typec_port *port = to_typec_port(kobj_to_dev(kobj)); 1950 1951 if (attr == &dev_attr_data_role.attr) { 1952 if (port->cap->data != TYPEC_PORT_DRD || 1953 !port->ops || !port->ops->dr_set) 1954 return 0444; 1955 } else if (attr == &dev_attr_power_role.attr) { 1956 if (port->cap->type != TYPEC_PORT_DRP || 1957 !port->ops || !port->ops->pr_set) 1958 return 0444; 1959 } else if (attr == &dev_attr_vconn_source.attr) { 1960 if (!port->cap->pd_revision || 1961 !port->ops || !port->ops->vconn_set) 1962 return 0444; 1963 } else if (attr == &dev_attr_preferred_role.attr) { 1964 if (port->cap->type != TYPEC_PORT_DRP || 1965 !port->ops || !port->ops->try_role) 1966 return 0444; 1967 } else if (attr == &dev_attr_port_type.attr) { 1968 if (!port->ops || !port->ops->port_type_set) 1969 return 0; 1970 if (port->cap->type != TYPEC_PORT_DRP) 1971 return 0444; 1972 } else if (attr == &dev_attr_orientation.attr) { 1973 if (port->cap->orientation_aware) 1974 return 0444; 1975 return 0; 1976 } else if (attr == &dev_attr_usb_capability.attr) { 1977 if (!port->cap->usb_capability) 1978 return 0; 1979 if (!port->ops || !port->ops->default_usb_mode_set) 1980 return 0444; 1981 } 1982 1983 return attr->mode; 1984} 1985 1986static const struct attribute_group typec_group = { 1987 .is_visible = typec_attr_is_visible, 1988 .attrs = typec_attrs, 1989}; 1990 1991static const struct attribute_group *typec_groups[] = { 1992 &typec_group, 1993 &pd_group, 1994 NULL 1995}; 1996 1997static int typec_uevent(const struct device *dev, struct kobj_uevent_env *env) 1998{ 1999 int ret; 2000 2001 ret = add_uevent_var(env, "TYPEC_PORT=%s", dev_name(dev)); 2002 if (ret) 2003 dev_err(dev, "failed to add uevent TYPEC_PORT\n"); 2004 2005 return ret; 2006} 2007 2008static void typec_release(struct device *dev) 2009{ 2010 struct typec_port *port = to_typec_port(dev); 2011 2012 ida_free(&typec_index_ida, port->id); 2013 ida_destroy(&port->mode_ids); 2014 typec_switch_put(port->sw); 2015 typec_mux_put(port->mux); 2016 typec_retimer_put(port->retimer); 2017 kfree(port->cap); 2018 kfree(port); 2019} 2020 2021const struct device_type typec_port_dev_type = { 2022 .name = "typec_port", 2023 .groups = typec_groups, 2024 .uevent = typec_uevent, 2025 .release = typec_release, 2026}; 2027 2028/* --------------------------------------- */ 2029/* Driver callbacks to report role updates */ 2030 2031static int partner_match(struct device *dev, void *data) 2032{ 2033 return is_typec_partner(dev); 2034} 2035 2036static struct typec_partner *typec_get_partner(struct typec_port *port) 2037{ 2038 struct device *dev; 2039 2040 dev = device_find_child(&port->dev, NULL, partner_match); 2041 if (!dev) 2042 return NULL; 2043 2044 return to_typec_partner(dev); 2045} 2046 2047static void typec_partner_attach(struct typec_connector *con, struct device *dev) 2048{ 2049 struct typec_port *port = container_of(con, struct typec_port, con); 2050 struct typec_partner *partner = typec_get_partner(port); 2051 struct usb_device *udev = to_usb_device(dev); 2052 enum usb_mode usb_mode; 2053 2054 if (udev->speed < USB_SPEED_SUPER) { 2055 usb_mode = USB_MODE_USB2; 2056 port->usb2_dev = dev; 2057 } else { 2058 usb_mode = USB_MODE_USB3; 2059 port->usb3_dev = dev; 2060 } 2061 2062 if (partner) { 2063 typec_partner_set_usb_mode(partner, usb_mode); 2064 typec_partner_link_device(partner, dev); 2065 put_device(&partner->dev); 2066 } 2067} 2068 2069static void typec_partner_deattach(struct typec_connector *con, struct device *dev) 2070{ 2071 struct typec_port *port = container_of(con, struct typec_port, con); 2072 struct typec_partner *partner = typec_get_partner(port); 2073 2074 if (partner) { 2075 typec_partner_unlink_device(partner, dev); 2076 put_device(&partner->dev); 2077 } 2078 2079 if (port->usb2_dev == dev) 2080 port->usb2_dev = NULL; 2081 else if (port->usb3_dev == dev) 2082 port->usb3_dev = NULL; 2083} 2084 2085/** 2086 * typec_set_data_role - Report data role change 2087 * @port: The USB Type-C Port where the role was changed 2088 * @role: The new data role 2089 * 2090 * This routine is used by the port drivers to report data role changes. 2091 */ 2092void typec_set_data_role(struct typec_port *port, enum typec_data_role role) 2093{ 2094 struct typec_partner *partner; 2095 2096 if (port->data_role == role) 2097 return; 2098 2099 port->data_role = role; 2100 sysfs_notify(&port->dev.kobj, NULL, "data_role"); 2101 kobject_uevent(&port->dev.kobj, KOBJ_CHANGE); 2102 2103 partner = typec_get_partner(port); 2104 if (!partner) 2105 return; 2106 2107 if (partner->identity) 2108 typec_product_type_notify(&partner->dev); 2109 2110 put_device(&partner->dev); 2111} 2112EXPORT_SYMBOL_GPL(typec_set_data_role); 2113 2114/** 2115 * typec_set_pwr_role - Report power role change 2116 * @port: The USB Type-C Port where the role was changed 2117 * @role: The new data role 2118 * 2119 * This routine is used by the port drivers to report power role changes. 2120 */ 2121void typec_set_pwr_role(struct typec_port *port, enum typec_role role) 2122{ 2123 if (port->pwr_role == role) 2124 return; 2125 2126 port->pwr_role = role; 2127 sysfs_notify(&port->dev.kobj, NULL, "power_role"); 2128 kobject_uevent(&port->dev.kobj, KOBJ_CHANGE); 2129} 2130EXPORT_SYMBOL_GPL(typec_set_pwr_role); 2131 2132/** 2133 * typec_set_vconn_role - Report VCONN source change 2134 * @port: The USB Type-C Port which VCONN role changed 2135 * @role: Source when @port is sourcing VCONN, or Sink when it's not 2136 * 2137 * This routine is used by the port drivers to report if the VCONN source is 2138 * changes. 2139 */ 2140void typec_set_vconn_role(struct typec_port *port, enum typec_role role) 2141{ 2142 if (port->vconn_role == role) 2143 return; 2144 2145 port->vconn_role = role; 2146 sysfs_notify(&port->dev.kobj, NULL, "vconn_source"); 2147 kobject_uevent(&port->dev.kobj, KOBJ_CHANGE); 2148} 2149EXPORT_SYMBOL_GPL(typec_set_vconn_role); 2150 2151/** 2152 * typec_set_pwr_opmode - Report changed power operation mode 2153 * @port: The USB Type-C Port where the mode was changed 2154 * @opmode: New power operation mode 2155 * 2156 * This routine is used by the port drivers to report changed power operation 2157 * mode in @port. The modes are USB (default), 1.5A, 3.0A as defined in USB 2158 * Type-C specification, and "USB Power Delivery" when the power levels are 2159 * negotiated with methods defined in USB Power Delivery specification. 2160 */ 2161void typec_set_pwr_opmode(struct typec_port *port, 2162 enum typec_pwr_opmode opmode) 2163{ 2164 struct device *partner_dev; 2165 2166 if (port->pwr_opmode == opmode) 2167 return; 2168 2169 port->pwr_opmode = opmode; 2170 sysfs_notify(&port->dev.kobj, NULL, "power_operation_mode"); 2171 kobject_uevent(&port->dev.kobj, KOBJ_CHANGE); 2172 2173 partner_dev = device_find_child(&port->dev, NULL, partner_match); 2174 if (partner_dev) { 2175 struct typec_partner *partner = to_typec_partner(partner_dev); 2176 2177 if (opmode == TYPEC_PWR_MODE_PD && !partner->usb_pd) { 2178 partner->usb_pd = 1; 2179 sysfs_notify(&partner_dev->kobj, NULL, 2180 "supports_usb_power_delivery"); 2181 kobject_uevent(&partner_dev->kobj, KOBJ_CHANGE); 2182 } 2183 put_device(partner_dev); 2184 } 2185} 2186EXPORT_SYMBOL_GPL(typec_set_pwr_opmode); 2187 2188/** 2189 * typec_find_pwr_opmode - Get the typec power operation mode capability 2190 * @name: power operation mode string 2191 * 2192 * This routine is used to find the typec_pwr_opmode by its string @name. 2193 * 2194 * Returns typec_pwr_opmode if success, otherwise negative error code. 2195 */ 2196int typec_find_pwr_opmode(const char *name) 2197{ 2198 return match_string(typec_pwr_opmodes, 2199 ARRAY_SIZE(typec_pwr_opmodes), name); 2200} 2201EXPORT_SYMBOL_GPL(typec_find_pwr_opmode); 2202 2203/** 2204 * typec_find_orientation - Convert orientation string to enum typec_orientation 2205 * @name: Orientation string 2206 * 2207 * This routine is used to find the typec_orientation by its string name @name. 2208 * 2209 * Returns the orientation value on success, otherwise negative error code. 2210 */ 2211int typec_find_orientation(const char *name) 2212{ 2213 return match_string(typec_orientations, ARRAY_SIZE(typec_orientations), 2214 name); 2215} 2216EXPORT_SYMBOL_GPL(typec_find_orientation); 2217 2218/** 2219 * typec_find_port_power_role - Get the typec port power capability 2220 * @name: port power capability string 2221 * 2222 * This routine is used to find the typec_port_type by its string name. 2223 * 2224 * Returns typec_port_type if success, otherwise negative error code. 2225 */ 2226int typec_find_port_power_role(const char *name) 2227{ 2228 return match_string(typec_port_power_roles, 2229 ARRAY_SIZE(typec_port_power_roles), name); 2230} 2231EXPORT_SYMBOL_GPL(typec_find_port_power_role); 2232 2233/** 2234 * typec_find_power_role - Find the typec one specific power role 2235 * @name: power role string 2236 * 2237 * This routine is used to find the typec_role by its string name. 2238 * 2239 * Returns typec_role if success, otherwise negative error code. 2240 */ 2241int typec_find_power_role(const char *name) 2242{ 2243 return match_string(typec_roles, ARRAY_SIZE(typec_roles), name); 2244} 2245EXPORT_SYMBOL_GPL(typec_find_power_role); 2246 2247/** 2248 * typec_find_port_data_role - Get the typec port data capability 2249 * @name: port data capability string 2250 * 2251 * This routine is used to find the typec_port_data by its string name. 2252 * 2253 * Returns typec_port_data if success, otherwise negative error code. 2254 */ 2255int typec_find_port_data_role(const char *name) 2256{ 2257 return match_string(typec_port_data_roles, 2258 ARRAY_SIZE(typec_port_data_roles), name); 2259} 2260EXPORT_SYMBOL_GPL(typec_find_port_data_role); 2261 2262/* ------------------------------------------ */ 2263/* API for Multiplexer/DeMultiplexer Switches */ 2264 2265/** 2266 * typec_set_orientation - Set USB Type-C cable plug orientation 2267 * @port: USB Type-C Port 2268 * @orientation: USB Type-C cable plug orientation 2269 * 2270 * Set cable plug orientation for @port. 2271 */ 2272int typec_set_orientation(struct typec_port *port, 2273 enum typec_orientation orientation) 2274{ 2275 int ret; 2276 2277 ret = typec_switch_set(port->sw, orientation); 2278 if (ret) 2279 return ret; 2280 2281 port->orientation = orientation; 2282 sysfs_notify(&port->dev.kobj, NULL, "orientation"); 2283 kobject_uevent(&port->dev.kobj, KOBJ_CHANGE); 2284 2285 return 0; 2286} 2287EXPORT_SYMBOL_GPL(typec_set_orientation); 2288 2289/** 2290 * typec_get_orientation - Get USB Type-C cable plug orientation 2291 * @port: USB Type-C Port 2292 * 2293 * Get current cable plug orientation for @port. 2294 */ 2295enum typec_orientation typec_get_orientation(struct typec_port *port) 2296{ 2297 return port->orientation; 2298} 2299EXPORT_SYMBOL_GPL(typec_get_orientation); 2300 2301/** 2302 * typec_set_mode - Set mode of operation for USB Type-C connector 2303 * @port: USB Type-C connector 2304 * @mode: Accessory Mode, USB Operation or Safe State 2305 * 2306 * Configure @port for Accessory Mode @mode. This function will configure the 2307 * muxes needed for @mode. 2308 */ 2309int typec_set_mode(struct typec_port *port, int mode) 2310{ 2311 struct typec_mux_state state = { }; 2312 2313 state.mode = mode; 2314 2315 return typec_mux_set(port->mux, &state); 2316} 2317EXPORT_SYMBOL_GPL(typec_set_mode); 2318 2319/* --------------------------------------- */ 2320 2321/** 2322 * typec_get_negotiated_svdm_version - Get negotiated SVDM Version 2323 * @port: USB Type-C Port. 2324 * 2325 * Get the negotiated SVDM Version. The Version is set to the port default 2326 * value stored in typec_capability on partner registration, and updated after 2327 * a successful Discover Identity if the negotiated value is less than the 2328 * default value. 2329 * 2330 * Returns usb_pd_svdm_ver if the partner has been registered otherwise -ENODEV. 2331 */ 2332int typec_get_negotiated_svdm_version(struct typec_port *port) 2333{ 2334 enum usb_pd_svdm_ver svdm_version; 2335 struct device *partner_dev; 2336 2337 partner_dev = device_find_child(&port->dev, NULL, partner_match); 2338 if (!partner_dev) 2339 return -ENODEV; 2340 2341 svdm_version = to_typec_partner(partner_dev)->svdm_version; 2342 put_device(partner_dev); 2343 2344 return svdm_version; 2345} 2346EXPORT_SYMBOL_GPL(typec_get_negotiated_svdm_version); 2347 2348/** 2349 * typec_get_cable_svdm_version - Get cable negotiated SVDM Version 2350 * @port: USB Type-C Port. 2351 * 2352 * Get the negotiated SVDM Version for the cable. The Version is set to the port 2353 * default value based on the PD Revision during cable registration, and updated 2354 * after a successful Discover Identity if the negotiated value is less than the 2355 * default. 2356 * 2357 * Returns usb_pd_svdm_ver if the cable has been registered otherwise -ENODEV. 2358 */ 2359int typec_get_cable_svdm_version(struct typec_port *port) 2360{ 2361 enum usb_pd_svdm_ver svdm_version; 2362 struct device *cable_dev; 2363 2364 cable_dev = device_find_child(&port->dev, NULL, cable_match); 2365 if (!cable_dev) 2366 return -ENODEV; 2367 2368 svdm_version = to_typec_cable(cable_dev)->svdm_version; 2369 put_device(cable_dev); 2370 2371 return svdm_version; 2372} 2373EXPORT_SYMBOL_GPL(typec_get_cable_svdm_version); 2374 2375/** 2376 * typec_cable_set_svdm_version - Set negotiated Structured VDM (SVDM) Version 2377 * @cable: USB Type-C Active Cable that supports SVDM 2378 * @svdm_version: Negotiated SVDM Version 2379 * 2380 * This routine is used to save the negotiated SVDM Version. 2381 */ 2382void typec_cable_set_svdm_version(struct typec_cable *cable, enum usb_pd_svdm_ver svdm_version) 2383{ 2384 cable->svdm_version = svdm_version; 2385} 2386EXPORT_SYMBOL_GPL(typec_cable_set_svdm_version); 2387 2388/** 2389 * typec_get_drvdata - Return private driver data pointer 2390 * @port: USB Type-C port 2391 */ 2392void *typec_get_drvdata(struct typec_port *port) 2393{ 2394 return dev_get_drvdata(&port->dev); 2395} 2396EXPORT_SYMBOL_GPL(typec_get_drvdata); 2397 2398int typec_get_fw_cap(struct typec_capability *cap, 2399 struct fwnode_handle *fwnode) 2400{ 2401 const char *cap_str; 2402 int ret; 2403 2404 cap->fwnode = fwnode; 2405 2406 ret = fwnode_property_read_string(fwnode, "power-role", &cap_str); 2407 if (ret < 0) 2408 return ret; 2409 2410 ret = typec_find_port_power_role(cap_str); 2411 if (ret < 0) 2412 return ret; 2413 cap->type = ret; 2414 2415 /* USB data support is optional */ 2416 ret = fwnode_property_read_string(fwnode, "data-role", &cap_str); 2417 if (ret == 0) { 2418 ret = typec_find_port_data_role(cap_str); 2419 if (ret < 0) 2420 return ret; 2421 cap->data = ret; 2422 } 2423 2424 /* Get the preferred power role for a DRP */ 2425 if (cap->type == TYPEC_PORT_DRP) { 2426 cap->prefer_role = TYPEC_NO_PREFERRED_ROLE; 2427 2428 ret = fwnode_property_read_string(fwnode, "try-power-role", &cap_str); 2429 if (ret == 0) { 2430 ret = typec_find_power_role(cap_str); 2431 if (ret < 0) 2432 return ret; 2433 cap->prefer_role = ret; 2434 } 2435 } 2436 2437 return 0; 2438} 2439EXPORT_SYMBOL_GPL(typec_get_fw_cap); 2440 2441/** 2442 * typec_port_register_altmode - Register USB Type-C Port Alternate Mode 2443 * @port: USB Type-C Port that supports the alternate mode 2444 * @desc: Description of the alternate mode 2445 * 2446 * This routine is used to register an alternate mode that @port is capable of 2447 * supporting. 2448 * 2449 * Returns handle to the alternate mode on success or ERR_PTR on failure. 2450 */ 2451struct typec_altmode * 2452typec_port_register_altmode(struct typec_port *port, 2453 const struct typec_altmode_desc *desc) 2454{ 2455 struct typec_altmode *adev; 2456 struct typec_mux *mux; 2457 struct typec_retimer *retimer; 2458 2459 mux = typec_mux_get(&port->dev); 2460 if (IS_ERR(mux)) 2461 return ERR_CAST(mux); 2462 2463 retimer = typec_retimer_get(&port->dev); 2464 if (IS_ERR(retimer)) { 2465 typec_mux_put(mux); 2466 return ERR_CAST(retimer); 2467 } 2468 2469 adev = typec_register_altmode(&port->dev, desc); 2470 if (IS_ERR(adev)) { 2471 typec_retimer_put(retimer); 2472 typec_mux_put(mux); 2473 } else { 2474 to_altmode(adev)->mux = mux; 2475 to_altmode(adev)->retimer = retimer; 2476 } 2477 2478 return adev; 2479} 2480EXPORT_SYMBOL_GPL(typec_port_register_altmode); 2481 2482void typec_port_register_altmodes(struct typec_port *port, 2483 const struct typec_altmode_ops *ops, void *drvdata, 2484 struct typec_altmode **altmodes, size_t n) 2485{ 2486 struct fwnode_handle *child; 2487 struct typec_altmode_desc desc; 2488 struct typec_altmode *alt; 2489 size_t index = 0; 2490 u16 svid; 2491 u32 vdo; 2492 int ret; 2493 2494 struct fwnode_handle *altmodes_node __free(fwnode_handle) = 2495 device_get_named_child_node(&port->dev, "altmodes"); 2496 2497 if (!altmodes_node) 2498 return; /* No altmodes specified */ 2499 2500 fwnode_for_each_child_node(altmodes_node, child) { 2501 ret = fwnode_property_read_u16(child, "svid", &svid); 2502 if (ret) { 2503 dev_err(&port->dev, "Error reading svid for altmode %s\n", 2504 fwnode_get_name(child)); 2505 continue; 2506 } 2507 2508 ret = fwnode_property_read_u32(child, "vdo", &vdo); 2509 if (ret) { 2510 dev_err(&port->dev, "Error reading vdo for altmode %s\n", 2511 fwnode_get_name(child)); 2512 continue; 2513 } 2514 2515 if (index >= n) { 2516 dev_err(&port->dev, "Error not enough space for altmode %s\n", 2517 fwnode_get_name(child)); 2518 continue; 2519 } 2520 2521 desc.svid = svid; 2522 desc.vdo = vdo; 2523 desc.mode = index + 1; 2524 alt = typec_port_register_altmode(port, &desc); 2525 if (IS_ERR(alt)) { 2526 dev_err(&port->dev, "Error registering altmode %s\n", 2527 fwnode_get_name(child)); 2528 continue; 2529 } 2530 2531 typec_altmode_set_ops(alt, ops); 2532 typec_altmode_set_drvdata(alt, drvdata); 2533 altmodes[index] = alt; 2534 index++; 2535 } 2536} 2537EXPORT_SYMBOL_GPL(typec_port_register_altmodes); 2538 2539/** 2540 * typec_port_register_cable_ops - Register typec_cable_ops to port altmodes 2541 * @altmodes: USB Type-C Port's altmode vector 2542 * @max_altmodes: The maximum number of alt modes supported by the port 2543 * @ops: Cable alternate mode vector 2544 */ 2545void typec_port_register_cable_ops(struct typec_altmode **altmodes, int max_altmodes, 2546 const struct typec_cable_ops *ops) 2547{ 2548 int i; 2549 2550 for (i = 0; i < max_altmodes; i++) { 2551 if (!altmodes[i]) 2552 return; 2553 altmodes[i]->cable_ops = ops; 2554 } 2555} 2556EXPORT_SYMBOL_GPL(typec_port_register_cable_ops); 2557 2558/** 2559 * typec_register_port - Register a USB Type-C Port 2560 * @parent: Parent device 2561 * @cap: Description of the port 2562 * 2563 * Registers a device for USB Type-C Port described in @cap. 2564 * 2565 * Returns handle to the port on success or ERR_PTR on failure. 2566 */ 2567struct typec_port *typec_register_port(struct device *parent, 2568 const struct typec_capability *cap) 2569{ 2570 struct typec_port *port; 2571 int ret; 2572 int id; 2573 2574 port = kzalloc(sizeof(*port), GFP_KERNEL); 2575 if (!port) 2576 return ERR_PTR(-ENOMEM); 2577 2578 id = ida_alloc(&typec_index_ida, GFP_KERNEL); 2579 if (id < 0) { 2580 kfree(port); 2581 return ERR_PTR(id); 2582 } 2583 2584 switch (cap->type) { 2585 case TYPEC_PORT_SRC: 2586 port->pwr_role = TYPEC_SOURCE; 2587 port->vconn_role = TYPEC_SOURCE; 2588 break; 2589 case TYPEC_PORT_SNK: 2590 port->pwr_role = TYPEC_SINK; 2591 port->vconn_role = TYPEC_SINK; 2592 break; 2593 case TYPEC_PORT_DRP: 2594 if (cap->prefer_role != TYPEC_NO_PREFERRED_ROLE) 2595 port->pwr_role = cap->prefer_role; 2596 else 2597 port->pwr_role = TYPEC_SINK; 2598 break; 2599 } 2600 2601 switch (cap->data) { 2602 case TYPEC_PORT_DFP: 2603 port->data_role = TYPEC_HOST; 2604 break; 2605 case TYPEC_PORT_UFP: 2606 port->data_role = TYPEC_DEVICE; 2607 break; 2608 case TYPEC_PORT_DRD: 2609 if (cap->prefer_role == TYPEC_SOURCE) 2610 port->data_role = TYPEC_HOST; 2611 else 2612 port->data_role = TYPEC_DEVICE; 2613 break; 2614 } 2615 2616 ida_init(&port->mode_ids); 2617 mutex_init(&port->port_type_lock); 2618 2619 port->id = id; 2620 port->ops = cap->ops; 2621 port->port_type = cap->type; 2622 port->prefer_role = cap->prefer_role; 2623 port->con.attach = typec_partner_attach; 2624 port->con.deattach = typec_partner_deattach; 2625 2626 if (cap->usb_capability & USB_CAPABILITY_USB4) 2627 port->usb_mode = USB_MODE_USB4; 2628 else if (cap->usb_capability & USB_CAPABILITY_USB3) 2629 port->usb_mode = USB_MODE_USB3; 2630 else if (cap->usb_capability & USB_CAPABILITY_USB2) 2631 port->usb_mode = USB_MODE_USB2; 2632 2633 device_initialize(&port->dev); 2634 port->dev.class = &typec_class; 2635 port->dev.parent = parent; 2636 port->dev.fwnode = cap->fwnode; 2637 port->dev.type = &typec_port_dev_type; 2638 dev_set_name(&port->dev, "port%d", id); 2639 dev_set_drvdata(&port->dev, cap->driver_data); 2640 2641 port->cap = kmemdup(cap, sizeof(*cap), GFP_KERNEL); 2642 if (!port->cap) { 2643 put_device(&port->dev); 2644 return ERR_PTR(-ENOMEM); 2645 } 2646 2647 port->sw = typec_switch_get(&port->dev); 2648 if (IS_ERR(port->sw)) { 2649 ret = PTR_ERR(port->sw); 2650 put_device(&port->dev); 2651 return ERR_PTR(ret); 2652 } 2653 2654 port->mux = typec_mux_get(&port->dev); 2655 if (IS_ERR(port->mux)) { 2656 ret = PTR_ERR(port->mux); 2657 put_device(&port->dev); 2658 return ERR_PTR(ret); 2659 } 2660 2661 port->retimer = typec_retimer_get(&port->dev); 2662 if (IS_ERR(port->retimer)) { 2663 ret = PTR_ERR(port->retimer); 2664 put_device(&port->dev); 2665 return ERR_PTR(ret); 2666 } 2667 2668 port->pd = cap->pd; 2669 2670 ret = device_add(&port->dev); 2671 if (ret) { 2672 dev_err(parent, "failed to register port (%d)\n", ret); 2673 put_device(&port->dev); 2674 return ERR_PTR(ret); 2675 } 2676 2677 ret = usb_power_delivery_link_device(port->pd, &port->dev); 2678 if (ret) { 2679 dev_err(&port->dev, "failed to link pd\n"); 2680 device_unregister(&port->dev); 2681 return ERR_PTR(ret); 2682 } 2683 2684 ret = typec_link_ports(port); 2685 if (ret) 2686 dev_warn(&port->dev, "failed to create symlinks (%d)\n", ret); 2687 2688 return port; 2689} 2690EXPORT_SYMBOL_GPL(typec_register_port); 2691 2692/** 2693 * typec_unregister_port - Unregister a USB Type-C Port 2694 * @port: The port to be unregistered 2695 * 2696 * Unregister device created with typec_register_port(). 2697 */ 2698void typec_unregister_port(struct typec_port *port) 2699{ 2700 if (!IS_ERR_OR_NULL(port)) { 2701 typec_unlink_ports(port); 2702 typec_port_set_usb_power_delivery(port, NULL); 2703 device_unregister(&port->dev); 2704 } 2705} 2706EXPORT_SYMBOL_GPL(typec_unregister_port); 2707 2708static int __init typec_init(void) 2709{ 2710 int ret; 2711 2712 ret = bus_register(&typec_bus); 2713 if (ret) 2714 return ret; 2715 2716 ret = class_register(&typec_mux_class); 2717 if (ret) 2718 goto err_unregister_bus; 2719 2720 ret = class_register(&retimer_class); 2721 if (ret) 2722 goto err_unregister_mux_class; 2723 2724 ret = class_register(&typec_class); 2725 if (ret) 2726 goto err_unregister_retimer_class; 2727 2728 ret = usb_power_delivery_init(); 2729 if (ret) 2730 goto err_unregister_class; 2731 2732 return 0; 2733 2734err_unregister_class: 2735 class_unregister(&typec_class); 2736 2737err_unregister_retimer_class: 2738 class_unregister(&retimer_class); 2739 2740err_unregister_mux_class: 2741 class_unregister(&typec_mux_class); 2742 2743err_unregister_bus: 2744 bus_unregister(&typec_bus); 2745 2746 return ret; 2747} 2748subsys_initcall(typec_init); 2749 2750static void __exit typec_exit(void) 2751{ 2752 usb_power_delivery_exit(); 2753 class_unregister(&typec_class); 2754 ida_destroy(&typec_index_ida); 2755 bus_unregister(&typec_bus); 2756 class_unregister(&typec_mux_class); 2757 class_unregister(&retimer_class); 2758} 2759module_exit(typec_exit); 2760 2761MODULE_AUTHOR("Heikki Krogerus <heikki.krogerus@linux.intel.com>"); 2762MODULE_LICENSE("GPL v2"); 2763MODULE_DESCRIPTION("USB Type-C Connector Class");