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 <[email protected]> 7 */ 8 9 #include <linux/device.h> 10 #include <linux/module.h> 11 #include <linux/mutex.h> 12 #include <linux/slab.h> 13 14 #include "bus.h" 15 16 struct typec_plug { 17 struct device dev; 18 enum typec_plug_index index; 19 struct ida mode_ids; 20 }; 21 22 struct typec_cable { 23 struct device dev; 24 enum typec_plug_type type; 25 struct usb_pd_identity *identity; 26 unsigned int active:1; 27 }; 28 29 struct typec_partner { 30 struct device dev; 31 unsigned int usb_pd:1; 32 struct usb_pd_identity *identity; 33 enum typec_accessory accessory; 34 struct ida mode_ids; 35 }; 36 37 struct typec_port { 38 unsigned int id; 39 struct device dev; 40 struct ida mode_ids; 41 42 int prefer_role; 43 enum typec_data_role data_role; 44 enum typec_role pwr_role; 45 enum typec_role vconn_role; 46 enum typec_pwr_opmode pwr_opmode; 47 enum typec_port_type port_type; 48 struct mutex port_type_lock; 49 50 enum typec_orientation orientation; 51 struct typec_switch *sw; 52 struct typec_mux *mux; 53 54 const struct typec_capability *cap; 55 }; 56 57 #define to_typec_port(_dev_) container_of(_dev_, struct typec_port, dev) 58 #define to_typec_plug(_dev_) container_of(_dev_, struct typec_plug, dev) 59 #define to_typec_cable(_dev_) container_of(_dev_, struct typec_cable, dev) 60 #define to_typec_partner(_dev_) container_of(_dev_, struct typec_partner, dev) 61 62 static const struct device_type typec_partner_dev_type; 63 static const struct device_type typec_cable_dev_type; 64 static const struct device_type typec_plug_dev_type; 65 66 #define is_typec_partner(_dev_) (_dev_->type == &typec_partner_dev_type) 67 #define is_typec_cable(_dev_) (_dev_->type == &typec_cable_dev_type) 68 #define is_typec_plug(_dev_) (_dev_->type == &typec_plug_dev_type) 69 70 static DEFINE_IDA(typec_index_ida); 71 static struct class *typec_class; 72 73 /* ------------------------------------------------------------------------- */ 74 /* Common attributes */ 75 76 static const char * const typec_accessory_modes[] = { 77 [TYPEC_ACCESSORY_NONE] = "none", 78 [TYPEC_ACCESSORY_AUDIO] = "analog_audio", 79 [TYPEC_ACCESSORY_DEBUG] = "debug", 80 }; 81 82 static struct usb_pd_identity *get_pd_identity(struct device *dev) 83 { 84 if (is_typec_partner(dev)) { 85 struct typec_partner *partner = to_typec_partner(dev); 86 87 return partner->identity; 88 } else if (is_typec_cable(dev)) { 89 struct typec_cable *cable = to_typec_cable(dev); 90 91 return cable->identity; 92 } 93 return NULL; 94 } 95 96 static ssize_t id_header_show(struct device *dev, struct device_attribute *attr, 97 char *buf) 98 { 99 struct usb_pd_identity *id = get_pd_identity(dev); 100 101 return sprintf(buf, "0x%08x\n", id->id_header); 102 } 103 static DEVICE_ATTR_RO(id_header); 104 105 static ssize_t cert_stat_show(struct device *dev, struct device_attribute *attr, 106 char *buf) 107 { 108 struct usb_pd_identity *id = get_pd_identity(dev); 109 110 return sprintf(buf, "0x%08x\n", id->cert_stat); 111 } 112 static DEVICE_ATTR_RO(cert_stat); 113 114 static ssize_t product_show(struct device *dev, struct device_attribute *attr, 115 char *buf) 116 { 117 struct usb_pd_identity *id = get_pd_identity(dev); 118 119 return sprintf(buf, "0x%08x\n", id->product); 120 } 121 static DEVICE_ATTR_RO(product); 122 123 static struct attribute *usb_pd_id_attrs[] = { 124 &dev_attr_id_header.attr, 125 &dev_attr_cert_stat.attr, 126 &dev_attr_product.attr, 127 NULL 128 }; 129 130 static const struct attribute_group usb_pd_id_group = { 131 .name = "identity", 132 .attrs = usb_pd_id_attrs, 133 }; 134 135 static const struct attribute_group *usb_pd_id_groups[] = { 136 &usb_pd_id_group, 137 NULL, 138 }; 139 140 static void typec_report_identity(struct device *dev) 141 { 142 sysfs_notify(&dev->kobj, "identity", "id_header"); 143 sysfs_notify(&dev->kobj, "identity", "cert_stat"); 144 sysfs_notify(&dev->kobj, "identity", "product"); 145 } 146 147 /* ------------------------------------------------------------------------- */ 148 /* Alternate Modes */ 149 150 static int altmode_match(struct device *dev, void *data) 151 { 152 struct typec_altmode *adev = to_typec_altmode(dev); 153 struct typec_device_id *id = data; 154 155 if (!is_typec_altmode(dev)) 156 return 0; 157 158 return ((adev->svid == id->svid) && (adev->mode == id->mode)); 159 } 160 161 static void typec_altmode_set_partner(struct altmode *altmode) 162 { 163 struct typec_altmode *adev = &altmode->adev; 164 struct typec_device_id id = { adev->svid, adev->mode, }; 165 struct typec_port *port = typec_altmode2port(adev); 166 struct altmode *partner; 167 struct device *dev; 168 169 dev = device_find_child(&port->dev, &id, altmode_match); 170 if (!dev) 171 return; 172 173 /* Bind the port alt mode to the partner/plug alt mode. */ 174 partner = to_altmode(to_typec_altmode(dev)); 175 altmode->partner = partner; 176 177 /* Bind the partner/plug alt mode to the port alt mode. */ 178 if (is_typec_plug(adev->dev.parent)) { 179 struct typec_plug *plug = to_typec_plug(adev->dev.parent); 180 181 partner->plug[plug->index] = altmode; 182 } else { 183 partner->partner = altmode; 184 } 185 } 186 187 static void typec_altmode_put_partner(struct altmode *altmode) 188 { 189 struct altmode *partner = altmode->partner; 190 struct typec_altmode *adev; 191 192 if (!partner) 193 return; 194 195 adev = &partner->adev; 196 197 if (is_typec_plug(adev->dev.parent)) { 198 struct typec_plug *plug = to_typec_plug(adev->dev.parent); 199 200 partner->plug[plug->index] = NULL; 201 } else { 202 partner->partner = NULL; 203 } 204 put_device(&adev->dev); 205 } 206 207 static int __typec_port_match(struct device *dev, const void *name) 208 { 209 return !strcmp((const char *)name, dev_name(dev)); 210 } 211 212 static void *typec_port_match(struct device_connection *con, int ep, void *data) 213 { 214 return class_find_device(typec_class, NULL, con->endpoint[ep], 215 __typec_port_match); 216 } 217 218 struct typec_altmode * 219 typec_altmode_register_notifier(struct device *dev, u16 svid, u8 mode, 220 struct notifier_block *nb) 221 { 222 struct typec_device_id id = { svid, mode, }; 223 struct device *altmode_dev; 224 struct device *port_dev; 225 struct altmode *altmode; 226 int ret; 227 228 /* Find the port linked to the caller */ 229 port_dev = device_connection_find_match(dev, NULL, NULL, 230 typec_port_match); 231 if (IS_ERR_OR_NULL(port_dev)) 232 return port_dev ? ERR_CAST(port_dev) : ERR_PTR(-ENODEV); 233 234 /* Find the altmode with matching svid */ 235 altmode_dev = device_find_child(port_dev, &id, altmode_match); 236 237 put_device(port_dev); 238 239 if (!altmode_dev) 240 return ERR_PTR(-ENODEV); 241 242 altmode = to_altmode(to_typec_altmode(altmode_dev)); 243 244 /* Register notifier */ 245 ret = blocking_notifier_chain_register(&altmode->nh, nb); 246 if (ret) { 247 put_device(altmode_dev); 248 return ERR_PTR(ret); 249 } 250 251 return &altmode->adev; 252 } 253 EXPORT_SYMBOL_GPL(typec_altmode_register_notifier); 254 255 void typec_altmode_unregister_notifier(struct typec_altmode *adev, 256 struct notifier_block *nb) 257 { 258 struct altmode *altmode = to_altmode(adev); 259 260 blocking_notifier_chain_unregister(&altmode->nh, nb); 261 put_device(&adev->dev); 262 } 263 EXPORT_SYMBOL_GPL(typec_altmode_unregister_notifier); 264 265 /** 266 * typec_altmode_update_active - Report Enter/Exit mode 267 * @adev: Handle to the alternate mode 268 * @active: True when the mode has been entered 269 * 270 * If a partner or cable plug executes Enter/Exit Mode command successfully, the 271 * drivers use this routine to report the updated state of the mode. 272 */ 273 void typec_altmode_update_active(struct typec_altmode *adev, bool active) 274 { 275 char dir[6]; 276 277 if (adev->active == active) 278 return; 279 280 if (!is_typec_port(adev->dev.parent)) { 281 if (!active) 282 module_put(adev->dev.driver->owner); 283 else 284 WARN_ON(!try_module_get(adev->dev.driver->owner)); 285 } 286 287 adev->active = active; 288 snprintf(dir, sizeof(dir), "mode%d", adev->mode); 289 sysfs_notify(&adev->dev.kobj, dir, "active"); 290 sysfs_notify(&adev->dev.kobj, NULL, "active"); 291 kobject_uevent(&adev->dev.kobj, KOBJ_CHANGE); 292 } 293 EXPORT_SYMBOL_GPL(typec_altmode_update_active); 294 295 /** 296 * typec_altmode2port - Alternate Mode to USB Type-C port 297 * @alt: The Alternate Mode 298 * 299 * Returns handle to the port that a cable plug or partner with @alt is 300 * connected to. 301 */ 302 struct typec_port *typec_altmode2port(struct typec_altmode *alt) 303 { 304 if (is_typec_plug(alt->dev.parent)) 305 return to_typec_port(alt->dev.parent->parent->parent); 306 if (is_typec_partner(alt->dev.parent)) 307 return to_typec_port(alt->dev.parent->parent); 308 if (is_typec_port(alt->dev.parent)) 309 return to_typec_port(alt->dev.parent); 310 311 return NULL; 312 } 313 EXPORT_SYMBOL_GPL(typec_altmode2port); 314 315 static ssize_t 316 vdo_show(struct device *dev, struct device_attribute *attr, char *buf) 317 { 318 struct typec_altmode *alt = to_typec_altmode(dev); 319 320 return sprintf(buf, "0x%08x\n", alt->vdo); 321 } 322 static DEVICE_ATTR_RO(vdo); 323 324 static ssize_t 325 description_show(struct device *dev, struct device_attribute *attr, char *buf) 326 { 327 struct typec_altmode *alt = to_typec_altmode(dev); 328 329 return sprintf(buf, "%s\n", alt->desc ? alt->desc : ""); 330 } 331 static DEVICE_ATTR_RO(description); 332 333 static ssize_t 334 active_show(struct device *dev, struct device_attribute *attr, char *buf) 335 { 336 struct typec_altmode *alt = to_typec_altmode(dev); 337 338 return sprintf(buf, "%s\n", alt->active ? "yes" : "no"); 339 } 340 341 static ssize_t active_store(struct device *dev, struct device_attribute *attr, 342 const char *buf, size_t size) 343 { 344 struct typec_altmode *adev = to_typec_altmode(dev); 345 struct altmode *altmode = to_altmode(adev); 346 bool enter; 347 int ret; 348 349 ret = kstrtobool(buf, &enter); 350 if (ret) 351 return ret; 352 353 if (adev->active == enter) 354 return size; 355 356 if (is_typec_port(adev->dev.parent)) { 357 typec_altmode_update_active(adev, enter); 358 359 /* Make sure that the partner exits the mode before disabling */ 360 if (altmode->partner && !enter && altmode->partner->adev.active) 361 typec_altmode_exit(&altmode->partner->adev); 362 } else if (altmode->partner) { 363 if (enter && !altmode->partner->adev.active) { 364 dev_warn(dev, "port has the mode disabled\n"); 365 return -EPERM; 366 } 367 } 368 369 /* Note: If there is no driver, the mode will not be entered */ 370 if (adev->ops && adev->ops->activate) { 371 ret = adev->ops->activate(adev, enter); 372 if (ret) 373 return ret; 374 } 375 376 return size; 377 } 378 static DEVICE_ATTR_RW(active); 379 380 static ssize_t 381 supported_roles_show(struct device *dev, struct device_attribute *attr, 382 char *buf) 383 { 384 struct altmode *alt = to_altmode(to_typec_altmode(dev)); 385 ssize_t ret; 386 387 switch (alt->roles) { 388 case TYPEC_PORT_SRC: 389 ret = sprintf(buf, "source\n"); 390 break; 391 case TYPEC_PORT_SNK: 392 ret = sprintf(buf, "sink\n"); 393 break; 394 case TYPEC_PORT_DRP: 395 default: 396 ret = sprintf(buf, "source sink\n"); 397 break; 398 } 399 return ret; 400 } 401 static DEVICE_ATTR_RO(supported_roles); 402 403 static ssize_t 404 mode_show(struct device *dev, struct device_attribute *attr, char *buf) 405 { 406 struct typec_altmode *adev = to_typec_altmode(dev); 407 408 return sprintf(buf, "%u\n", adev->mode); 409 } 410 static DEVICE_ATTR_RO(mode); 411 412 static ssize_t 413 svid_show(struct device *dev, struct device_attribute *attr, char *buf) 414 { 415 struct typec_altmode *adev = to_typec_altmode(dev); 416 417 return sprintf(buf, "%04x\n", adev->svid); 418 } 419 static DEVICE_ATTR_RO(svid); 420 421 static struct attribute *typec_altmode_attrs[] = { 422 &dev_attr_active.attr, 423 &dev_attr_mode.attr, 424 &dev_attr_svid.attr, 425 &dev_attr_vdo.attr, 426 NULL 427 }; 428 ATTRIBUTE_GROUPS(typec_altmode); 429 430 static int altmode_id_get(struct device *dev) 431 { 432 struct ida *ids; 433 434 if (is_typec_partner(dev)) 435 ids = &to_typec_partner(dev)->mode_ids; 436 else if (is_typec_plug(dev)) 437 ids = &to_typec_plug(dev)->mode_ids; 438 else 439 ids = &to_typec_port(dev)->mode_ids; 440 441 return ida_simple_get(ids, 0, 0, GFP_KERNEL); 442 } 443 444 static void altmode_id_remove(struct device *dev, int id) 445 { 446 struct ida *ids; 447 448 if (is_typec_partner(dev)) 449 ids = &to_typec_partner(dev)->mode_ids; 450 else if (is_typec_plug(dev)) 451 ids = &to_typec_plug(dev)->mode_ids; 452 else 453 ids = &to_typec_port(dev)->mode_ids; 454 455 ida_simple_remove(ids, id); 456 } 457 458 static void typec_altmode_release(struct device *dev) 459 { 460 struct altmode *alt = to_altmode(to_typec_altmode(dev)); 461 462 typec_altmode_put_partner(alt); 463 464 altmode_id_remove(alt->adev.dev.parent, alt->id); 465 kfree(alt); 466 } 467 468 const struct device_type typec_altmode_dev_type = { 469 .name = "typec_alternate_mode", 470 .groups = typec_altmode_groups, 471 .release = typec_altmode_release, 472 }; 473 474 static struct typec_altmode * 475 typec_register_altmode(struct device *parent, 476 const struct typec_altmode_desc *desc) 477 { 478 unsigned int id = altmode_id_get(parent); 479 bool is_port = is_typec_port(parent); 480 struct altmode *alt; 481 int ret; 482 483 alt = kzalloc(sizeof(*alt), GFP_KERNEL); 484 if (!alt) 485 return ERR_PTR(-ENOMEM); 486 487 alt->adev.svid = desc->svid; 488 alt->adev.mode = desc->mode; 489 alt->adev.vdo = desc->vdo; 490 alt->roles = desc->roles; 491 alt->id = id; 492 493 alt->attrs[0] = &dev_attr_vdo.attr; 494 alt->attrs[1] = &dev_attr_description.attr; 495 alt->attrs[2] = &dev_attr_active.attr; 496 497 if (is_port) { 498 alt->attrs[3] = &dev_attr_supported_roles.attr; 499 alt->adev.active = true; /* Enabled by default */ 500 } 501 502 sprintf(alt->group_name, "mode%d", desc->mode); 503 alt->group.name = alt->group_name; 504 alt->group.attrs = alt->attrs; 505 alt->groups[0] = &alt->group; 506 507 alt->adev.dev.parent = parent; 508 alt->adev.dev.groups = alt->groups; 509 alt->adev.dev.type = &typec_altmode_dev_type; 510 dev_set_name(&alt->adev.dev, "%s.%u", dev_name(parent), id); 511 512 /* Link partners and plugs with the ports */ 513 if (is_port) 514 BLOCKING_INIT_NOTIFIER_HEAD(&alt->nh); 515 else 516 typec_altmode_set_partner(alt); 517 518 /* The partners are bind to drivers */ 519 if (is_typec_partner(parent)) 520 alt->adev.dev.bus = &typec_bus; 521 522 ret = device_register(&alt->adev.dev); 523 if (ret) { 524 dev_err(parent, "failed to register alternate mode (%d)\n", 525 ret); 526 put_device(&alt->adev.dev); 527 return ERR_PTR(ret); 528 } 529 530 return &alt->adev; 531 } 532 533 /** 534 * typec_unregister_altmode - Unregister Alternate Mode 535 * @adev: The alternate mode to be unregistered 536 * 537 * Unregister device created with typec_partner_register_altmode(), 538 * typec_plug_register_altmode() or typec_port_register_altmode(). 539 */ 540 void typec_unregister_altmode(struct typec_altmode *adev) 541 { 542 if (IS_ERR_OR_NULL(adev)) 543 return; 544 typec_mux_put(to_altmode(adev)->mux); 545 device_unregister(&adev->dev); 546 } 547 EXPORT_SYMBOL_GPL(typec_unregister_altmode); 548 549 /* ------------------------------------------------------------------------- */ 550 /* Type-C Partners */ 551 552 static ssize_t accessory_mode_show(struct device *dev, 553 struct device_attribute *attr, 554 char *buf) 555 { 556 struct typec_partner *p = to_typec_partner(dev); 557 558 return sprintf(buf, "%s\n", typec_accessory_modes[p->accessory]); 559 } 560 static DEVICE_ATTR_RO(accessory_mode); 561 562 static ssize_t supports_usb_power_delivery_show(struct device *dev, 563 struct device_attribute *attr, 564 char *buf) 565 { 566 struct typec_partner *p = to_typec_partner(dev); 567 568 return sprintf(buf, "%s\n", p->usb_pd ? "yes" : "no"); 569 } 570 static DEVICE_ATTR_RO(supports_usb_power_delivery); 571 572 static struct attribute *typec_partner_attrs[] = { 573 &dev_attr_accessory_mode.attr, 574 &dev_attr_supports_usb_power_delivery.attr, 575 NULL 576 }; 577 ATTRIBUTE_GROUPS(typec_partner); 578 579 static void typec_partner_release(struct device *dev) 580 { 581 struct typec_partner *partner = to_typec_partner(dev); 582 583 ida_destroy(&partner->mode_ids); 584 kfree(partner); 585 } 586 587 static const struct device_type typec_partner_dev_type = { 588 .name = "typec_partner", 589 .groups = typec_partner_groups, 590 .release = typec_partner_release, 591 }; 592 593 /** 594 * typec_partner_set_identity - Report result from Discover Identity command 595 * @partner: The partner updated identity values 596 * 597 * This routine is used to report that the result of Discover Identity USB power 598 * delivery command has become available. 599 */ 600 int typec_partner_set_identity(struct typec_partner *partner) 601 { 602 if (!partner->identity) 603 return -EINVAL; 604 605 typec_report_identity(&partner->dev); 606 return 0; 607 } 608 EXPORT_SYMBOL_GPL(typec_partner_set_identity); 609 610 /** 611 * typec_partner_register_altmode - Register USB Type-C Partner Alternate Mode 612 * @partner: USB Type-C Partner that supports the alternate mode 613 * @desc: Description of the alternate mode 614 * 615 * This routine is used to register each alternate mode individually that 616 * @partner has listed in response to Discover SVIDs command. The modes for a 617 * SVID listed in response to Discover Modes command need to be listed in an 618 * array in @desc. 619 * 620 * Returns handle to the alternate mode on success or NULL on failure. 621 */ 622 struct typec_altmode * 623 typec_partner_register_altmode(struct typec_partner *partner, 624 const struct typec_altmode_desc *desc) 625 { 626 return typec_register_altmode(&partner->dev, desc); 627 } 628 EXPORT_SYMBOL_GPL(typec_partner_register_altmode); 629 630 /** 631 * typec_register_partner - Register a USB Type-C Partner 632 * @port: The USB Type-C Port the partner is connected to 633 * @desc: Description of the partner 634 * 635 * Registers a device for USB Type-C Partner described in @desc. 636 * 637 * Returns handle to the partner on success or ERR_PTR on failure. 638 */ 639 struct typec_partner *typec_register_partner(struct typec_port *port, 640 struct typec_partner_desc *desc) 641 { 642 struct typec_partner *partner; 643 int ret; 644 645 partner = kzalloc(sizeof(*partner), GFP_KERNEL); 646 if (!partner) 647 return ERR_PTR(-ENOMEM); 648 649 ida_init(&partner->mode_ids); 650 partner->usb_pd = desc->usb_pd; 651 partner->accessory = desc->accessory; 652 653 if (desc->identity) { 654 /* 655 * Creating directory for the identity only if the driver is 656 * able to provide data to it. 657 */ 658 partner->dev.groups = usb_pd_id_groups; 659 partner->identity = desc->identity; 660 } 661 662 partner->dev.class = typec_class; 663 partner->dev.parent = &port->dev; 664 partner->dev.type = &typec_partner_dev_type; 665 dev_set_name(&partner->dev, "%s-partner", dev_name(&port->dev)); 666 667 ret = device_register(&partner->dev); 668 if (ret) { 669 dev_err(&port->dev, "failed to register partner (%d)\n", ret); 670 put_device(&partner->dev); 671 return ERR_PTR(ret); 672 } 673 674 return partner; 675 } 676 EXPORT_SYMBOL_GPL(typec_register_partner); 677 678 /** 679 * typec_unregister_partner - Unregister a USB Type-C Partner 680 * @partner: The partner to be unregistered 681 * 682 * Unregister device created with typec_register_partner(). 683 */ 684 void typec_unregister_partner(struct typec_partner *partner) 685 { 686 if (!IS_ERR_OR_NULL(partner)) 687 device_unregister(&partner->dev); 688 } 689 EXPORT_SYMBOL_GPL(typec_unregister_partner); 690 691 /* ------------------------------------------------------------------------- */ 692 /* Type-C Cable Plugs */ 693 694 static void typec_plug_release(struct device *dev) 695 { 696 struct typec_plug *plug = to_typec_plug(dev); 697 698 ida_destroy(&plug->mode_ids); 699 kfree(plug); 700 } 701 702 static const struct device_type typec_plug_dev_type = { 703 .name = "typec_plug", 704 .release = typec_plug_release, 705 }; 706 707 /** 708 * typec_plug_register_altmode - Register USB Type-C Cable Plug Alternate Mode 709 * @plug: USB Type-C Cable Plug that supports the alternate mode 710 * @desc: Description of the alternate mode 711 * 712 * This routine is used to register each alternate mode individually that @plug 713 * has listed in response to Discover SVIDs command. The modes for a SVID that 714 * the plug lists in response to Discover Modes command need to be listed in an 715 * array in @desc. 716 * 717 * Returns handle to the alternate mode on success or ERR_PTR on failure. 718 */ 719 struct typec_altmode * 720 typec_plug_register_altmode(struct typec_plug *plug, 721 const struct typec_altmode_desc *desc) 722 { 723 return typec_register_altmode(&plug->dev, desc); 724 } 725 EXPORT_SYMBOL_GPL(typec_plug_register_altmode); 726 727 /** 728 * typec_register_plug - Register a USB Type-C Cable Plug 729 * @cable: USB Type-C Cable with the plug 730 * @desc: Description of the cable plug 731 * 732 * Registers a device for USB Type-C Cable Plug described in @desc. A USB Type-C 733 * Cable Plug represents a plug with electronics in it that can response to USB 734 * Power Delivery SOP Prime or SOP Double Prime packages. 735 * 736 * Returns handle to the cable plug on success or ERR_PTR on failure. 737 */ 738 struct typec_plug *typec_register_plug(struct typec_cable *cable, 739 struct typec_plug_desc *desc) 740 { 741 struct typec_plug *plug; 742 char name[8]; 743 int ret; 744 745 plug = kzalloc(sizeof(*plug), GFP_KERNEL); 746 if (!plug) 747 return ERR_PTR(-ENOMEM); 748 749 sprintf(name, "plug%d", desc->index); 750 751 ida_init(&plug->mode_ids); 752 plug->index = desc->index; 753 plug->dev.class = typec_class; 754 plug->dev.parent = &cable->dev; 755 plug->dev.type = &typec_plug_dev_type; 756 dev_set_name(&plug->dev, "%s-%s", dev_name(cable->dev.parent), name); 757 758 ret = device_register(&plug->dev); 759 if (ret) { 760 dev_err(&cable->dev, "failed to register plug (%d)\n", ret); 761 put_device(&plug->dev); 762 return ERR_PTR(ret); 763 } 764 765 return plug; 766 } 767 EXPORT_SYMBOL_GPL(typec_register_plug); 768 769 /** 770 * typec_unregister_plug - Unregister a USB Type-C Cable Plug 771 * @plug: The cable plug to be unregistered 772 * 773 * Unregister device created with typec_register_plug(). 774 */ 775 void typec_unregister_plug(struct typec_plug *plug) 776 { 777 if (!IS_ERR_OR_NULL(plug)) 778 device_unregister(&plug->dev); 779 } 780 EXPORT_SYMBOL_GPL(typec_unregister_plug); 781 782 /* Type-C Cables */ 783 784 static ssize_t 785 type_show(struct device *dev, struct device_attribute *attr, char *buf) 786 { 787 struct typec_cable *cable = to_typec_cable(dev); 788 789 return sprintf(buf, "%s\n", cable->active ? "active" : "passive"); 790 } 791 static DEVICE_ATTR_RO(type); 792 793 static const char * const typec_plug_types[] = { 794 [USB_PLUG_NONE] = "unknown", 795 [USB_PLUG_TYPE_A] = "type-a", 796 [USB_PLUG_TYPE_B] = "type-b", 797 [USB_PLUG_TYPE_C] = "type-c", 798 [USB_PLUG_CAPTIVE] = "captive", 799 }; 800 801 static ssize_t plug_type_show(struct device *dev, 802 struct device_attribute *attr, char *buf) 803 { 804 struct typec_cable *cable = to_typec_cable(dev); 805 806 return sprintf(buf, "%s\n", typec_plug_types[cable->type]); 807 } 808 static DEVICE_ATTR_RO(plug_type); 809 810 static struct attribute *typec_cable_attrs[] = { 811 &dev_attr_type.attr, 812 &dev_attr_plug_type.attr, 813 NULL 814 }; 815 ATTRIBUTE_GROUPS(typec_cable); 816 817 static void typec_cable_release(struct device *dev) 818 { 819 struct typec_cable *cable = to_typec_cable(dev); 820 821 kfree(cable); 822 } 823 824 static const struct device_type typec_cable_dev_type = { 825 .name = "typec_cable", 826 .groups = typec_cable_groups, 827 .release = typec_cable_release, 828 }; 829 830 /** 831 * typec_cable_set_identity - Report result from Discover Identity command 832 * @cable: The cable updated identity values 833 * 834 * This routine is used to report that the result of Discover Identity USB power 835 * delivery command has become available. 836 */ 837 int typec_cable_set_identity(struct typec_cable *cable) 838 { 839 if (!cable->identity) 840 return -EINVAL; 841 842 typec_report_identity(&cable->dev); 843 return 0; 844 } 845 EXPORT_SYMBOL_GPL(typec_cable_set_identity); 846 847 /** 848 * typec_register_cable - Register a USB Type-C Cable 849 * @port: The USB Type-C Port the cable is connected to 850 * @desc: Description of the cable 851 * 852 * Registers a device for USB Type-C Cable described in @desc. The cable will be 853 * parent for the optional cable plug devises. 854 * 855 * Returns handle to the cable on success or ERR_PTR on failure. 856 */ 857 struct typec_cable *typec_register_cable(struct typec_port *port, 858 struct typec_cable_desc *desc) 859 { 860 struct typec_cable *cable; 861 int ret; 862 863 cable = kzalloc(sizeof(*cable), GFP_KERNEL); 864 if (!cable) 865 return ERR_PTR(-ENOMEM); 866 867 cable->type = desc->type; 868 cable->active = desc->active; 869 870 if (desc->identity) { 871 /* 872 * Creating directory for the identity only if the driver is 873 * able to provide data to it. 874 */ 875 cable->dev.groups = usb_pd_id_groups; 876 cable->identity = desc->identity; 877 } 878 879 cable->dev.class = typec_class; 880 cable->dev.parent = &port->dev; 881 cable->dev.type = &typec_cable_dev_type; 882 dev_set_name(&cable->dev, "%s-cable", dev_name(&port->dev)); 883 884 ret = device_register(&cable->dev); 885 if (ret) { 886 dev_err(&port->dev, "failed to register cable (%d)\n", ret); 887 put_device(&cable->dev); 888 return ERR_PTR(ret); 889 } 890 891 return cable; 892 } 893 EXPORT_SYMBOL_GPL(typec_register_cable); 894 895 /** 896 * typec_unregister_cable - Unregister a USB Type-C Cable 897 * @cable: The cable to be unregistered 898 * 899 * Unregister device created with typec_register_cable(). 900 */ 901 void typec_unregister_cable(struct typec_cable *cable) 902 { 903 if (!IS_ERR_OR_NULL(cable)) 904 device_unregister(&cable->dev); 905 } 906 EXPORT_SYMBOL_GPL(typec_unregister_cable); 907 908 /* ------------------------------------------------------------------------- */ 909 /* USB Type-C ports */ 910 911 static const char * const typec_roles[] = { 912 [TYPEC_SINK] = "sink", 913 [TYPEC_SOURCE] = "source", 914 }; 915 916 static const char * const typec_data_roles[] = { 917 [TYPEC_DEVICE] = "device", 918 [TYPEC_HOST] = "host", 919 }; 920 921 static const char * const typec_port_power_roles[] = { 922 [TYPEC_PORT_SRC] = "source", 923 [TYPEC_PORT_SNK] = "sink", 924 [TYPEC_PORT_DRP] = "dual", 925 }; 926 927 static const char * const typec_port_data_roles[] = { 928 [TYPEC_PORT_DFP] = "host", 929 [TYPEC_PORT_UFP] = "device", 930 [TYPEC_PORT_DRD] = "dual", 931 }; 932 933 static const char * const typec_port_types_drp[] = { 934 [TYPEC_PORT_SRC] = "dual [source] sink", 935 [TYPEC_PORT_SNK] = "dual source [sink]", 936 [TYPEC_PORT_DRP] = "[dual] source sink", 937 }; 938 939 static ssize_t 940 preferred_role_store(struct device *dev, struct device_attribute *attr, 941 const char *buf, size_t size) 942 { 943 struct typec_port *port = to_typec_port(dev); 944 int role; 945 int ret; 946 947 if (port->cap->type != TYPEC_PORT_DRP) { 948 dev_dbg(dev, "Preferred role only supported with DRP ports\n"); 949 return -EOPNOTSUPP; 950 } 951 952 if (!port->cap->try_role) { 953 dev_dbg(dev, "Setting preferred role not supported\n"); 954 return -EOPNOTSUPP; 955 } 956 957 role = sysfs_match_string(typec_roles, buf); 958 if (role < 0) { 959 if (sysfs_streq(buf, "none")) 960 role = TYPEC_NO_PREFERRED_ROLE; 961 else 962 return -EINVAL; 963 } 964 965 ret = port->cap->try_role(port->cap, role); 966 if (ret) 967 return ret; 968 969 port->prefer_role = role; 970 return size; 971 } 972 973 static ssize_t 974 preferred_role_show(struct device *dev, struct device_attribute *attr, 975 char *buf) 976 { 977 struct typec_port *port = to_typec_port(dev); 978 979 if (port->cap->type != TYPEC_PORT_DRP) 980 return 0; 981 982 if (port->prefer_role < 0) 983 return 0; 984 985 return sprintf(buf, "%s\n", typec_roles[port->prefer_role]); 986 } 987 static DEVICE_ATTR_RW(preferred_role); 988 989 static ssize_t data_role_store(struct device *dev, 990 struct device_attribute *attr, 991 const char *buf, size_t size) 992 { 993 struct typec_port *port = to_typec_port(dev); 994 int ret; 995 996 if (!port->cap->dr_set) { 997 dev_dbg(dev, "data role swapping not supported\n"); 998 return -EOPNOTSUPP; 999 } 1000 1001 ret = sysfs_match_string(typec_data_roles, buf); 1002 if (ret < 0) 1003 return ret; 1004 1005 mutex_lock(&port->port_type_lock); 1006 if (port->cap->data != TYPEC_PORT_DRD) { 1007 ret = -EOPNOTSUPP; 1008 goto unlock_and_ret; 1009 } 1010 1011 ret = port->cap->dr_set(port->cap, ret); 1012 if (ret) 1013 goto unlock_and_ret; 1014 1015 ret = size; 1016 unlock_and_ret: 1017 mutex_unlock(&port->port_type_lock); 1018 return ret; 1019 } 1020 1021 static ssize_t data_role_show(struct device *dev, 1022 struct device_attribute *attr, char *buf) 1023 { 1024 struct typec_port *port = to_typec_port(dev); 1025 1026 if (port->cap->data == TYPEC_PORT_DRD) 1027 return sprintf(buf, "%s\n", port->data_role == TYPEC_HOST ? 1028 "[host] device" : "host [device]"); 1029 1030 return sprintf(buf, "[%s]\n", typec_data_roles[port->data_role]); 1031 } 1032 static DEVICE_ATTR_RW(data_role); 1033 1034 static ssize_t power_role_store(struct device *dev, 1035 struct device_attribute *attr, 1036 const char *buf, size_t size) 1037 { 1038 struct typec_port *port = to_typec_port(dev); 1039 int ret; 1040 1041 if (!port->cap->pd_revision) { 1042 dev_dbg(dev, "USB Power Delivery not supported\n"); 1043 return -EOPNOTSUPP; 1044 } 1045 1046 if (!port->cap->pr_set) { 1047 dev_dbg(dev, "power role swapping not supported\n"); 1048 return -EOPNOTSUPP; 1049 } 1050 1051 if (port->pwr_opmode != TYPEC_PWR_MODE_PD) { 1052 dev_dbg(dev, "partner unable to swap power role\n"); 1053 return -EIO; 1054 } 1055 1056 ret = sysfs_match_string(typec_roles, buf); 1057 if (ret < 0) 1058 return ret; 1059 1060 mutex_lock(&port->port_type_lock); 1061 if (port->port_type != TYPEC_PORT_DRP) { 1062 dev_dbg(dev, "port type fixed at \"%s\"", 1063 typec_port_power_roles[port->port_type]); 1064 ret = -EOPNOTSUPP; 1065 goto unlock_and_ret; 1066 } 1067 1068 ret = port->cap->pr_set(port->cap, ret); 1069 if (ret) 1070 goto unlock_and_ret; 1071 1072 ret = size; 1073 unlock_and_ret: 1074 mutex_unlock(&port->port_type_lock); 1075 return ret; 1076 } 1077 1078 static ssize_t power_role_show(struct device *dev, 1079 struct device_attribute *attr, char *buf) 1080 { 1081 struct typec_port *port = to_typec_port(dev); 1082 1083 if (port->cap->type == TYPEC_PORT_DRP) 1084 return sprintf(buf, "%s\n", port->pwr_role == TYPEC_SOURCE ? 1085 "[source] sink" : "source [sink]"); 1086 1087 return sprintf(buf, "[%s]\n", typec_roles[port->pwr_role]); 1088 } 1089 static DEVICE_ATTR_RW(power_role); 1090 1091 static ssize_t 1092 port_type_store(struct device *dev, struct device_attribute *attr, 1093 const char *buf, size_t size) 1094 { 1095 struct typec_port *port = to_typec_port(dev); 1096 int ret; 1097 enum typec_port_type type; 1098 1099 if (!port->cap->port_type_set || port->cap->type != TYPEC_PORT_DRP) { 1100 dev_dbg(dev, "changing port type not supported\n"); 1101 return -EOPNOTSUPP; 1102 } 1103 1104 ret = sysfs_match_string(typec_port_power_roles, buf); 1105 if (ret < 0) 1106 return ret; 1107 1108 type = ret; 1109 mutex_lock(&port->port_type_lock); 1110 1111 if (port->port_type == type) { 1112 ret = size; 1113 goto unlock_and_ret; 1114 } 1115 1116 ret = port->cap->port_type_set(port->cap, type); 1117 if (ret) 1118 goto unlock_and_ret; 1119 1120 port->port_type = type; 1121 ret = size; 1122 1123 unlock_and_ret: 1124 mutex_unlock(&port->port_type_lock); 1125 return ret; 1126 } 1127 1128 static ssize_t 1129 port_type_show(struct device *dev, struct device_attribute *attr, 1130 char *buf) 1131 { 1132 struct typec_port *port = to_typec_port(dev); 1133 1134 if (port->cap->type == TYPEC_PORT_DRP) 1135 return sprintf(buf, "%s\n", 1136 typec_port_types_drp[port->port_type]); 1137 1138 return sprintf(buf, "[%s]\n", typec_port_power_roles[port->cap->type]); 1139 } 1140 static DEVICE_ATTR_RW(port_type); 1141 1142 static const char * const typec_pwr_opmodes[] = { 1143 [TYPEC_PWR_MODE_USB] = "default", 1144 [TYPEC_PWR_MODE_1_5A] = "1.5A", 1145 [TYPEC_PWR_MODE_3_0A] = "3.0A", 1146 [TYPEC_PWR_MODE_PD] = "usb_power_delivery", 1147 }; 1148 1149 static ssize_t power_operation_mode_show(struct device *dev, 1150 struct device_attribute *attr, 1151 char *buf) 1152 { 1153 struct typec_port *port = to_typec_port(dev); 1154 1155 return sprintf(buf, "%s\n", typec_pwr_opmodes[port->pwr_opmode]); 1156 } 1157 static DEVICE_ATTR_RO(power_operation_mode); 1158 1159 static ssize_t vconn_source_store(struct device *dev, 1160 struct device_attribute *attr, 1161 const char *buf, size_t size) 1162 { 1163 struct typec_port *port = to_typec_port(dev); 1164 bool source; 1165 int ret; 1166 1167 if (!port->cap->pd_revision) { 1168 dev_dbg(dev, "VCONN swap depends on USB Power Delivery\n"); 1169 return -EOPNOTSUPP; 1170 } 1171 1172 if (!port->cap->vconn_set) { 1173 dev_dbg(dev, "VCONN swapping not supported\n"); 1174 return -EOPNOTSUPP; 1175 } 1176 1177 ret = kstrtobool(buf, &source); 1178 if (ret) 1179 return ret; 1180 1181 ret = port->cap->vconn_set(port->cap, (enum typec_role)source); 1182 if (ret) 1183 return ret; 1184 1185 return size; 1186 } 1187 1188 static ssize_t vconn_source_show(struct device *dev, 1189 struct device_attribute *attr, char *buf) 1190 { 1191 struct typec_port *port = to_typec_port(dev); 1192 1193 return sprintf(buf, "%s\n", 1194 port->vconn_role == TYPEC_SOURCE ? "yes" : "no"); 1195 } 1196 static DEVICE_ATTR_RW(vconn_source); 1197 1198 static ssize_t supported_accessory_modes_show(struct device *dev, 1199 struct device_attribute *attr, 1200 char *buf) 1201 { 1202 struct typec_port *port = to_typec_port(dev); 1203 ssize_t ret = 0; 1204 int i; 1205 1206 for (i = 0; i < ARRAY_SIZE(port->cap->accessory); i++) { 1207 if (port->cap->accessory[i]) 1208 ret += sprintf(buf + ret, "%s ", 1209 typec_accessory_modes[port->cap->accessory[i]]); 1210 } 1211 1212 if (!ret) 1213 return sprintf(buf, "none\n"); 1214 1215 buf[ret - 1] = '\n'; 1216 1217 return ret; 1218 } 1219 static DEVICE_ATTR_RO(supported_accessory_modes); 1220 1221 static ssize_t usb_typec_revision_show(struct device *dev, 1222 struct device_attribute *attr, 1223 char *buf) 1224 { 1225 struct typec_port *port = to_typec_port(dev); 1226 u16 rev = port->cap->revision; 1227 1228 return sprintf(buf, "%d.%d\n", (rev >> 8) & 0xff, (rev >> 4) & 0xf); 1229 } 1230 static DEVICE_ATTR_RO(usb_typec_revision); 1231 1232 static ssize_t usb_power_delivery_revision_show(struct device *dev, 1233 struct device_attribute *attr, 1234 char *buf) 1235 { 1236 struct typec_port *p = to_typec_port(dev); 1237 1238 return sprintf(buf, "%d\n", (p->cap->pd_revision >> 8) & 0xff); 1239 } 1240 static DEVICE_ATTR_RO(usb_power_delivery_revision); 1241 1242 static struct attribute *typec_attrs[] = { 1243 &dev_attr_data_role.attr, 1244 &dev_attr_power_operation_mode.attr, 1245 &dev_attr_power_role.attr, 1246 &dev_attr_preferred_role.attr, 1247 &dev_attr_supported_accessory_modes.attr, 1248 &dev_attr_usb_power_delivery_revision.attr, 1249 &dev_attr_usb_typec_revision.attr, 1250 &dev_attr_vconn_source.attr, 1251 &dev_attr_port_type.attr, 1252 NULL, 1253 }; 1254 ATTRIBUTE_GROUPS(typec); 1255 1256 static int typec_uevent(struct device *dev, struct kobj_uevent_env *env) 1257 { 1258 int ret; 1259 1260 ret = add_uevent_var(env, "TYPEC_PORT=%s", dev_name(dev)); 1261 if (ret) 1262 dev_err(dev, "failed to add uevent TYPEC_PORT\n"); 1263 1264 return ret; 1265 } 1266 1267 static void typec_release(struct device *dev) 1268 { 1269 struct typec_port *port = to_typec_port(dev); 1270 1271 ida_simple_remove(&typec_index_ida, port->id); 1272 ida_destroy(&port->mode_ids); 1273 typec_switch_put(port->sw); 1274 typec_mux_put(port->mux); 1275 kfree(port); 1276 } 1277 1278 const struct device_type typec_port_dev_type = { 1279 .name = "typec_port", 1280 .groups = typec_groups, 1281 .uevent = typec_uevent, 1282 .release = typec_release, 1283 }; 1284 1285 /* --------------------------------------- */ 1286 /* Driver callbacks to report role updates */ 1287 1288 /** 1289 * typec_set_data_role - Report data role change 1290 * @port: The USB Type-C Port where the role was changed 1291 * @role: The new data role 1292 * 1293 * This routine is used by the port drivers to report data role changes. 1294 */ 1295 void typec_set_data_role(struct typec_port *port, enum typec_data_role role) 1296 { 1297 if (port->data_role == role) 1298 return; 1299 1300 port->data_role = role; 1301 sysfs_notify(&port->dev.kobj, NULL, "data_role"); 1302 kobject_uevent(&port->dev.kobj, KOBJ_CHANGE); 1303 } 1304 EXPORT_SYMBOL_GPL(typec_set_data_role); 1305 1306 /** 1307 * typec_set_pwr_role - Report power role change 1308 * @port: The USB Type-C Port where the role was changed 1309 * @role: The new data role 1310 * 1311 * This routine is used by the port drivers to report power role changes. 1312 */ 1313 void typec_set_pwr_role(struct typec_port *port, enum typec_role role) 1314 { 1315 if (port->pwr_role == role) 1316 return; 1317 1318 port->pwr_role = role; 1319 sysfs_notify(&port->dev.kobj, NULL, "power_role"); 1320 kobject_uevent(&port->dev.kobj, KOBJ_CHANGE); 1321 } 1322 EXPORT_SYMBOL_GPL(typec_set_pwr_role); 1323 1324 /** 1325 * typec_set_pwr_role - Report VCONN source change 1326 * @port: The USB Type-C Port which VCONN role changed 1327 * @role: Source when @port is sourcing VCONN, or Sink when it's not 1328 * 1329 * This routine is used by the port drivers to report if the VCONN source is 1330 * changes. 1331 */ 1332 void typec_set_vconn_role(struct typec_port *port, enum typec_role role) 1333 { 1334 if (port->vconn_role == role) 1335 return; 1336 1337 port->vconn_role = role; 1338 sysfs_notify(&port->dev.kobj, NULL, "vconn_source"); 1339 kobject_uevent(&port->dev.kobj, KOBJ_CHANGE); 1340 } 1341 EXPORT_SYMBOL_GPL(typec_set_vconn_role); 1342 1343 static int partner_match(struct device *dev, void *data) 1344 { 1345 return is_typec_partner(dev); 1346 } 1347 1348 /** 1349 * typec_set_pwr_opmode - Report changed power operation mode 1350 * @port: The USB Type-C Port where the mode was changed 1351 * @opmode: New power operation mode 1352 * 1353 * This routine is used by the port drivers to report changed power operation 1354 * mode in @port. The modes are USB (default), 1.5A, 3.0A as defined in USB 1355 * Type-C specification, and "USB Power Delivery" when the power levels are 1356 * negotiated with methods defined in USB Power Delivery specification. 1357 */ 1358 void typec_set_pwr_opmode(struct typec_port *port, 1359 enum typec_pwr_opmode opmode) 1360 { 1361 struct device *partner_dev; 1362 1363 if (port->pwr_opmode == opmode) 1364 return; 1365 1366 port->pwr_opmode = opmode; 1367 sysfs_notify(&port->dev.kobj, NULL, "power_operation_mode"); 1368 kobject_uevent(&port->dev.kobj, KOBJ_CHANGE); 1369 1370 partner_dev = device_find_child(&port->dev, NULL, partner_match); 1371 if (partner_dev) { 1372 struct typec_partner *partner = to_typec_partner(partner_dev); 1373 1374 if (opmode == TYPEC_PWR_MODE_PD && !partner->usb_pd) { 1375 partner->usb_pd = 1; 1376 sysfs_notify(&partner_dev->kobj, NULL, 1377 "supports_usb_power_delivery"); 1378 } 1379 put_device(partner_dev); 1380 } 1381 } 1382 EXPORT_SYMBOL_GPL(typec_set_pwr_opmode); 1383 1384 /** 1385 * typec_find_port_power_role - Get the typec port power capability 1386 * @name: port power capability string 1387 * 1388 * This routine is used to find the typec_port_type by its string name. 1389 * 1390 * Returns typec_port_type if success, otherwise negative error code. 1391 */ 1392 int typec_find_port_power_role(const char *name) 1393 { 1394 return match_string(typec_port_power_roles, 1395 ARRAY_SIZE(typec_port_power_roles), name); 1396 } 1397 EXPORT_SYMBOL_GPL(typec_find_port_power_role); 1398 1399 /** 1400 * typec_find_power_role - Find the typec one specific power role 1401 * @name: power role string 1402 * 1403 * This routine is used to find the typec_role by its string name. 1404 * 1405 * Returns typec_role if success, otherwise negative error code. 1406 */ 1407 int typec_find_power_role(const char *name) 1408 { 1409 return match_string(typec_roles, ARRAY_SIZE(typec_roles), name); 1410 } 1411 EXPORT_SYMBOL_GPL(typec_find_power_role); 1412 1413 /** 1414 * typec_find_port_data_role - Get the typec port data capability 1415 * @name: port data capability string 1416 * 1417 * This routine is used to find the typec_port_data by its string name. 1418 * 1419 * Returns typec_port_data if success, otherwise negative error code. 1420 */ 1421 int typec_find_port_data_role(const char *name) 1422 { 1423 return match_string(typec_port_data_roles, 1424 ARRAY_SIZE(typec_port_data_roles), name); 1425 } 1426 EXPORT_SYMBOL_GPL(typec_find_port_data_role); 1427 1428 /* ------------------------------------------ */ 1429 /* API for Multiplexer/DeMultiplexer Switches */ 1430 1431 /** 1432 * typec_set_orientation - Set USB Type-C cable plug orientation 1433 * @port: USB Type-C Port 1434 * @orientation: USB Type-C cable plug orientation 1435 * 1436 * Set cable plug orientation for @port. 1437 */ 1438 int typec_set_orientation(struct typec_port *port, 1439 enum typec_orientation orientation) 1440 { 1441 int ret; 1442 1443 if (port->sw) { 1444 ret = port->sw->set(port->sw, orientation); 1445 if (ret) 1446 return ret; 1447 } 1448 1449 port->orientation = orientation; 1450 1451 return 0; 1452 } 1453 EXPORT_SYMBOL_GPL(typec_set_orientation); 1454 1455 /** 1456 * typec_get_orientation - Get USB Type-C cable plug orientation 1457 * @port: USB Type-C Port 1458 * 1459 * Get current cable plug orientation for @port. 1460 */ 1461 enum typec_orientation typec_get_orientation(struct typec_port *port) 1462 { 1463 return port->orientation; 1464 } 1465 EXPORT_SYMBOL_GPL(typec_get_orientation); 1466 1467 /** 1468 * typec_set_mode - Set mode of operation for USB Type-C connector 1469 * @port: USB Type-C connector 1470 * @mode: Accessory Mode, USB Operation or Safe State 1471 * 1472 * Configure @port for Accessory Mode @mode. This function will configure the 1473 * muxes needed for @mode. 1474 */ 1475 int typec_set_mode(struct typec_port *port, int mode) 1476 { 1477 return port->mux ? port->mux->set(port->mux, mode) : 0; 1478 } 1479 EXPORT_SYMBOL_GPL(typec_set_mode); 1480 1481 /* --------------------------------------- */ 1482 1483 /** 1484 * typec_port_register_altmode - Register USB Type-C Port Alternate Mode 1485 * @port: USB Type-C Port that supports the alternate mode 1486 * @desc: Description of the alternate mode 1487 * @drvdata: Private pointer to driver specific info 1488 * 1489 * This routine is used to register an alternate mode that @port is capable of 1490 * supporting. 1491 * 1492 * Returns handle to the alternate mode on success or ERR_PTR on failure. 1493 */ 1494 struct typec_altmode * 1495 typec_port_register_altmode(struct typec_port *port, 1496 const struct typec_altmode_desc *desc) 1497 { 1498 struct typec_altmode *adev; 1499 struct typec_mux *mux; 1500 char id[10]; 1501 1502 sprintf(id, "id%04xm%02x", desc->svid, desc->mode); 1503 1504 mux = typec_mux_get(port->dev.parent, id); 1505 if (IS_ERR(mux)) 1506 return ERR_CAST(mux); 1507 1508 adev = typec_register_altmode(&port->dev, desc); 1509 if (IS_ERR(adev)) 1510 typec_mux_put(mux); 1511 else 1512 to_altmode(adev)->mux = mux; 1513 1514 return adev; 1515 } 1516 EXPORT_SYMBOL_GPL(typec_port_register_altmode); 1517 1518 /** 1519 * typec_register_port - Register a USB Type-C Port 1520 * @parent: Parent device 1521 * @cap: Description of the port 1522 * 1523 * Registers a device for USB Type-C Port described in @cap. 1524 * 1525 * Returns handle to the port on success or ERR_PTR on failure. 1526 */ 1527 struct typec_port *typec_register_port(struct device *parent, 1528 const struct typec_capability *cap) 1529 { 1530 struct typec_port *port; 1531 int ret; 1532 int id; 1533 1534 port = kzalloc(sizeof(*port), GFP_KERNEL); 1535 if (!port) 1536 return ERR_PTR(-ENOMEM); 1537 1538 id = ida_simple_get(&typec_index_ida, 0, 0, GFP_KERNEL); 1539 if (id < 0) { 1540 kfree(port); 1541 return ERR_PTR(id); 1542 } 1543 1544 port->sw = typec_switch_get(cap->fwnode ? &port->dev : parent); 1545 if (IS_ERR(port->sw)) { 1546 ret = PTR_ERR(port->sw); 1547 goto err_switch; 1548 } 1549 1550 port->mux = typec_mux_get(parent, "typec-mux"); 1551 if (IS_ERR(port->mux)) { 1552 ret = PTR_ERR(port->mux); 1553 goto err_mux; 1554 } 1555 1556 switch (cap->type) { 1557 case TYPEC_PORT_SRC: 1558 port->pwr_role = TYPEC_SOURCE; 1559 port->vconn_role = TYPEC_SOURCE; 1560 break; 1561 case TYPEC_PORT_SNK: 1562 port->pwr_role = TYPEC_SINK; 1563 port->vconn_role = TYPEC_SINK; 1564 break; 1565 case TYPEC_PORT_DRP: 1566 if (cap->prefer_role != TYPEC_NO_PREFERRED_ROLE) 1567 port->pwr_role = cap->prefer_role; 1568 else 1569 port->pwr_role = TYPEC_SINK; 1570 break; 1571 } 1572 1573 switch (cap->data) { 1574 case TYPEC_PORT_DFP: 1575 port->data_role = TYPEC_HOST; 1576 break; 1577 case TYPEC_PORT_UFP: 1578 port->data_role = TYPEC_DEVICE; 1579 break; 1580 case TYPEC_PORT_DRD: 1581 if (cap->prefer_role == TYPEC_SOURCE) 1582 port->data_role = TYPEC_HOST; 1583 else 1584 port->data_role = TYPEC_DEVICE; 1585 break; 1586 } 1587 1588 ida_init(&port->mode_ids); 1589 mutex_init(&port->port_type_lock); 1590 1591 port->id = id; 1592 port->cap = cap; 1593 port->port_type = cap->type; 1594 port->prefer_role = cap->prefer_role; 1595 1596 port->dev.class = typec_class; 1597 port->dev.parent = parent; 1598 port->dev.fwnode = cap->fwnode; 1599 port->dev.type = &typec_port_dev_type; 1600 dev_set_name(&port->dev, "port%d", id); 1601 1602 ret = device_register(&port->dev); 1603 if (ret) { 1604 dev_err(parent, "failed to register port (%d)\n", ret); 1605 put_device(&port->dev); 1606 return ERR_PTR(ret); 1607 } 1608 1609 return port; 1610 1611 err_mux: 1612 typec_switch_put(port->sw); 1613 1614 err_switch: 1615 ida_simple_remove(&typec_index_ida, port->id); 1616 kfree(port); 1617 1618 return ERR_PTR(ret); 1619 } 1620 EXPORT_SYMBOL_GPL(typec_register_port); 1621 1622 /** 1623 * typec_unregister_port - Unregister a USB Type-C Port 1624 * @port: The port to be unregistered 1625 * 1626 * Unregister device created with typec_register_port(). 1627 */ 1628 void typec_unregister_port(struct typec_port *port) 1629 { 1630 if (!IS_ERR_OR_NULL(port)) 1631 device_unregister(&port->dev); 1632 } 1633 EXPORT_SYMBOL_GPL(typec_unregister_port); 1634 1635 static int __init typec_init(void) 1636 { 1637 int ret; 1638 1639 ret = bus_register(&typec_bus); 1640 if (ret) 1641 return ret; 1642 1643 typec_class = class_create(THIS_MODULE, "typec"); 1644 if (IS_ERR(typec_class)) { 1645 bus_unregister(&typec_bus); 1646 return PTR_ERR(typec_class); 1647 } 1648 1649 return 0; 1650 } 1651 subsys_initcall(typec_init); 1652 1653 static void __exit typec_exit(void) 1654 { 1655 class_destroy(typec_class); 1656 ida_destroy(&typec_index_ida); 1657 bus_unregister(&typec_bus); 1658 } 1659 module_exit(typec_exit); 1660 1661 MODULE_AUTHOR("Heikki Krogerus <[email protected]>"); 1662 MODULE_LICENSE("GPL v2"); 1663 MODULE_DESCRIPTION("USB Type-C Connector Class"); 1664