1 // SPDX-License-Identifier: GPL-2.0
3 * USB Type-C Connector Class
5 * Copyright (C) 2017, Intel Corporation
6 * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
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>
22 static DEFINE_IDA(typec_index_ida
);
24 const struct class typec_class
= {
28 /* ------------------------------------------------------------------------- */
29 /* Common attributes */
31 static const char * const typec_accessory_modes
[] = {
32 [TYPEC_ACCESSORY_NONE
] = "none",
33 [TYPEC_ACCESSORY_AUDIO
] = "analog_audio",
34 [TYPEC_ACCESSORY_DEBUG
] = "debug",
37 /* Product types defined in USB PD Specification R3.0 V2.0 */
38 static 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",
46 static 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",
53 static 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",
60 static struct usb_pd_identity
*get_pd_identity(struct device
*dev
)
62 if (is_typec_partner(dev
)) {
63 struct typec_partner
*partner
= to_typec_partner(dev
);
65 return partner
->identity
;
66 } else if (is_typec_cable(dev
)) {
67 struct typec_cable
*cable
= to_typec_cable(dev
);
69 return cable
->identity
;
74 static const char *get_pd_product_type(struct device
*dev
)
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
;
80 if (is_typec_partner(dev
)) {
84 if (port
->data_role
== TYPEC_HOST
)
85 ptype
= product_type_ufp
[PD_IDH_PTYPE(id
->id_header
)];
87 ptype
= product_type_dfp
[PD_IDH_DFP_PTYPE(id
->id_header
)];
88 } else if (is_typec_cable(dev
)) {
90 ptype
= product_type_cable
[PD_IDH_PTYPE(id
->id_header
)];
92 ptype
= to_typec_cable(dev
)->active
?
93 product_type_cable
[IDH_PTYPE_ACABLE
] :
94 product_type_cable
[IDH_PTYPE_PCABLE
];
100 static ssize_t
id_header_show(struct device
*dev
, struct device_attribute
*attr
,
103 struct usb_pd_identity
*id
= get_pd_identity(dev
);
105 return sprintf(buf
, "0x%08x\n", id
->id_header
);
107 static DEVICE_ATTR_RO(id_header
);
109 static ssize_t
cert_stat_show(struct device
*dev
, struct device_attribute
*attr
,
112 struct usb_pd_identity
*id
= get_pd_identity(dev
);
114 return sprintf(buf
, "0x%08x\n", id
->cert_stat
);
116 static DEVICE_ATTR_RO(cert_stat
);
118 static ssize_t
product_show(struct device
*dev
, struct device_attribute
*attr
,
121 struct usb_pd_identity
*id
= get_pd_identity(dev
);
123 return sprintf(buf
, "0x%08x\n", id
->product
);
125 static DEVICE_ATTR_RO(product
);
127 static ssize_t
product_type_vdo1_show(struct device
*dev
, struct device_attribute
*attr
,
130 struct usb_pd_identity
*id
= get_pd_identity(dev
);
132 return sysfs_emit(buf
, "0x%08x\n", id
->vdo
[0]);
134 static DEVICE_ATTR_RO(product_type_vdo1
);
136 static ssize_t
product_type_vdo2_show(struct device
*dev
, struct device_attribute
*attr
,
139 struct usb_pd_identity
*id
= get_pd_identity(dev
);
141 return sysfs_emit(buf
, "0x%08x\n", id
->vdo
[1]);
143 static DEVICE_ATTR_RO(product_type_vdo2
);
145 static ssize_t
product_type_vdo3_show(struct device
*dev
, struct device_attribute
*attr
,
148 struct usb_pd_identity
*id
= get_pd_identity(dev
);
150 return sysfs_emit(buf
, "0x%08x\n", id
->vdo
[2]);
152 static DEVICE_ATTR_RO(product_type_vdo3
);
154 static 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
,
164 static const struct attribute_group usb_pd_id_group
= {
166 .attrs
= usb_pd_id_attrs
,
169 static const struct attribute_group
*usb_pd_id_groups
[] = {
174 static void typec_product_type_notify(struct device
*dev
)
179 ptype
= get_pd_product_type(dev
);
183 sysfs_notify(&dev
->kobj
, NULL
, "type");
185 envp
[0] = kasprintf(GFP_KERNEL
, "PRODUCT_TYPE=%s", ptype
);
189 kobject_uevent_env(&dev
->kobj
, KOBJ_CHANGE
, envp
);
193 static void typec_report_identity(struct device
*dev
)
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
);
205 type_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
209 ptype
= get_pd_product_type(dev
);
213 return sysfs_emit(buf
, "%s\n", ptype
);
215 static DEVICE_ATTR_RO(type
);
217 static ssize_t
usb_power_delivery_revision_show(struct device
*dev
,
218 struct device_attribute
*attr
,
220 static DEVICE_ATTR_RO(usb_power_delivery_revision
);
222 /* ------------------------------------------------------------------------- */
223 /* Alternate Modes */
225 static int altmode_match(struct device
*dev
, void *data
)
227 struct typec_altmode
*adev
= to_typec_altmode(dev
);
228 struct typec_device_id
*id
= data
;
230 if (!is_typec_altmode(dev
))
233 return ((adev
->svid
== id
->svid
) && (adev
->mode
== id
->mode
));
236 static void typec_altmode_set_partner(struct altmode
*altmode
)
238 struct typec_altmode
*adev
= &altmode
->adev
;
239 struct typec_device_id id
= { adev
->svid
, adev
->mode
, };
240 struct typec_port
*port
= typec_altmode2port(adev
);
241 struct altmode
*partner
;
244 dev
= device_find_child(&port
->dev
, &id
, altmode_match
);
248 /* Bind the port alt mode to the partner/plug alt mode. */
249 partner
= to_altmode(to_typec_altmode(dev
));
250 altmode
->partner
= partner
;
252 /* Bind the partner/plug alt mode to the port alt mode. */
253 if (is_typec_plug(adev
->dev
.parent
)) {
254 struct typec_plug
*plug
= to_typec_plug(adev
->dev
.parent
);
256 partner
->plug
[plug
->index
] = altmode
;
258 partner
->partner
= altmode
;
262 static void typec_altmode_put_partner(struct altmode
*altmode
)
264 struct altmode
*partner
= altmode
->partner
;
265 struct typec_altmode
*adev
;
266 struct typec_altmode
*partner_adev
;
271 adev
= &altmode
->adev
;
272 partner_adev
= &partner
->adev
;
274 if (is_typec_plug(adev
->dev
.parent
)) {
275 struct typec_plug
*plug
= to_typec_plug(adev
->dev
.parent
);
277 partner
->plug
[plug
->index
] = NULL
;
279 partner
->partner
= NULL
;
281 put_device(&partner_adev
->dev
);
285 * typec_altmode_update_active - Report Enter/Exit mode
286 * @adev: Handle to the alternate mode
287 * @active: True when the mode has been entered
289 * If a partner or cable plug executes Enter/Exit Mode command successfully, the
290 * drivers use this routine to report the updated state of the mode.
292 void typec_altmode_update_active(struct typec_altmode
*adev
, bool active
)
296 if (adev
->active
== active
)
299 if (!is_typec_port(adev
->dev
.parent
) && adev
->dev
.driver
) {
301 module_put(adev
->dev
.driver
->owner
);
303 WARN_ON(!try_module_get(adev
->dev
.driver
->owner
));
306 adev
->active
= active
;
307 snprintf(dir
, sizeof(dir
), "mode%d", adev
->mode
);
308 sysfs_notify(&adev
->dev
.kobj
, dir
, "active");
309 sysfs_notify(&adev
->dev
.kobj
, NULL
, "active");
310 kobject_uevent(&adev
->dev
.kobj
, KOBJ_CHANGE
);
312 EXPORT_SYMBOL_GPL(typec_altmode_update_active
);
315 * typec_altmode2port - Alternate Mode to USB Type-C port
316 * @alt: The Alternate Mode
318 * Returns handle to the port that a cable plug or partner with @alt is
321 struct typec_port
*typec_altmode2port(struct typec_altmode
*alt
)
323 if (is_typec_plug(alt
->dev
.parent
))
324 return to_typec_port(alt
->dev
.parent
->parent
->parent
);
325 if (is_typec_partner(alt
->dev
.parent
))
326 return to_typec_port(alt
->dev
.parent
->parent
);
327 if (is_typec_port(alt
->dev
.parent
))
328 return to_typec_port(alt
->dev
.parent
);
332 EXPORT_SYMBOL_GPL(typec_altmode2port
);
335 vdo_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
337 struct typec_altmode
*alt
= to_typec_altmode(dev
);
339 return sprintf(buf
, "0x%08x\n", alt
->vdo
);
341 static DEVICE_ATTR_RO(vdo
);
344 description_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
346 struct typec_altmode
*alt
= to_typec_altmode(dev
);
348 return sprintf(buf
, "%s\n", alt
->desc
? alt
->desc
: "");
350 static DEVICE_ATTR_RO(description
);
353 active_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
355 struct typec_altmode
*alt
= to_typec_altmode(dev
);
357 return sprintf(buf
, "%s\n", alt
->active
? "yes" : "no");
360 static ssize_t
active_store(struct device
*dev
, struct device_attribute
*attr
,
361 const char *buf
, size_t size
)
363 struct typec_altmode
*adev
= to_typec_altmode(dev
);
364 struct altmode
*altmode
= to_altmode(adev
);
368 ret
= kstrtobool(buf
, &enter
);
372 if (adev
->active
== enter
)
375 if (is_typec_port(adev
->dev
.parent
)) {
376 typec_altmode_update_active(adev
, enter
);
378 /* Make sure that the partner exits the mode before disabling */
379 if (altmode
->partner
&& !enter
&& altmode
->partner
->adev
.active
)
380 typec_altmode_exit(&altmode
->partner
->adev
);
381 } else if (altmode
->partner
) {
382 if (enter
&& !altmode
->partner
->adev
.active
) {
383 dev_warn(dev
, "port has the mode disabled\n");
388 /* Note: If there is no driver, the mode will not be entered */
389 if (adev
->ops
&& adev
->ops
->activate
) {
390 ret
= adev
->ops
->activate(adev
, enter
);
397 static DEVICE_ATTR_RW(active
);
400 supported_roles_show(struct device
*dev
, struct device_attribute
*attr
,
403 struct altmode
*alt
= to_altmode(to_typec_altmode(dev
));
406 switch (alt
->roles
) {
408 ret
= sprintf(buf
, "source\n");
411 ret
= sprintf(buf
, "sink\n");
415 ret
= sprintf(buf
, "source sink\n");
420 static DEVICE_ATTR_RO(supported_roles
);
423 mode_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
425 struct typec_altmode
*adev
= to_typec_altmode(dev
);
427 return sprintf(buf
, "%u\n", adev
->mode
);
429 static DEVICE_ATTR_RO(mode
);
432 svid_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
434 struct typec_altmode
*adev
= to_typec_altmode(dev
);
436 return sprintf(buf
, "%04x\n", adev
->svid
);
438 static DEVICE_ATTR_RO(svid
);
440 static struct attribute
*typec_altmode_attrs
[] = {
441 &dev_attr_active
.attr
,
448 static umode_t
typec_altmode_attr_is_visible(struct kobject
*kobj
,
449 struct attribute
*attr
, int n
)
451 struct typec_altmode
*adev
= to_typec_altmode(kobj_to_dev(kobj
));
453 if (attr
== &dev_attr_active
.attr
)
454 if (!adev
->ops
|| !adev
->ops
->activate
)
460 static const struct attribute_group typec_altmode_group
= {
461 .is_visible
= typec_altmode_attr_is_visible
,
462 .attrs
= typec_altmode_attrs
,
465 static const struct attribute_group
*typec_altmode_groups
[] = {
466 &typec_altmode_group
,
471 * typec_altmode_set_ops - Set ops for altmode
472 * @adev: Handle to the alternate mode
473 * @ops: Ops for the alternate mode
475 * After setting ops, attribute visiblity needs to be refreshed if the alternate
476 * mode can be activated.
478 void typec_altmode_set_ops(struct typec_altmode
*adev
,
479 const struct typec_altmode_ops
*ops
)
482 sysfs_update_group(&adev
->dev
.kobj
, &typec_altmode_group
);
484 EXPORT_SYMBOL_GPL(typec_altmode_set_ops
);
486 static int altmode_id_get(struct device
*dev
)
490 if (is_typec_partner(dev
))
491 ids
= &to_typec_partner(dev
)->mode_ids
;
492 else if (is_typec_plug(dev
))
493 ids
= &to_typec_plug(dev
)->mode_ids
;
495 ids
= &to_typec_port(dev
)->mode_ids
;
497 return ida_alloc(ids
, GFP_KERNEL
);
500 static void altmode_id_remove(struct device
*dev
, int id
)
504 if (is_typec_partner(dev
))
505 ids
= &to_typec_partner(dev
)->mode_ids
;
506 else if (is_typec_plug(dev
))
507 ids
= &to_typec_plug(dev
)->mode_ids
;
509 ids
= &to_typec_port(dev
)->mode_ids
;
514 static void typec_altmode_release(struct device
*dev
)
516 struct altmode
*alt
= to_altmode(to_typec_altmode(dev
));
518 if (!is_typec_port(dev
->parent
))
519 typec_altmode_put_partner(alt
);
521 altmode_id_remove(alt
->adev
.dev
.parent
, alt
->id
);
522 put_device(alt
->adev
.dev
.parent
);
526 const struct device_type typec_altmode_dev_type
= {
527 .name
= "typec_alternate_mode",
528 .groups
= typec_altmode_groups
,
529 .release
= typec_altmode_release
,
532 static struct typec_altmode
*
533 typec_register_altmode(struct device
*parent
,
534 const struct typec_altmode_desc
*desc
)
536 unsigned int id
= altmode_id_get(parent
);
537 bool is_port
= is_typec_port(parent
);
541 alt
= kzalloc(sizeof(*alt
), GFP_KERNEL
);
543 altmode_id_remove(parent
, id
);
544 return ERR_PTR(-ENOMEM
);
547 alt
->adev
.svid
= desc
->svid
;
548 alt
->adev
.mode
= desc
->mode
;
549 alt
->adev
.vdo
= desc
->vdo
;
550 alt
->roles
= desc
->roles
;
553 alt
->attrs
[0] = &dev_attr_vdo
.attr
;
554 alt
->attrs
[1] = &dev_attr_description
.attr
;
555 alt
->attrs
[2] = &dev_attr_active
.attr
;
558 alt
->attrs
[3] = &dev_attr_supported_roles
.attr
;
559 alt
->adev
.active
= true; /* Enabled by default */
562 sprintf(alt
->group_name
, "mode%d", desc
->mode
);
563 alt
->group
.name
= alt
->group_name
;
564 alt
->group
.attrs
= alt
->attrs
;
565 alt
->groups
[0] = &alt
->group
;
567 alt
->adev
.dev
.parent
= parent
;
568 alt
->adev
.dev
.groups
= alt
->groups
;
569 alt
->adev
.dev
.type
= &typec_altmode_dev_type
;
570 dev_set_name(&alt
->adev
.dev
, "%s.%u", dev_name(parent
), id
);
572 get_device(alt
->adev
.dev
.parent
);
574 /* Link partners and plugs with the ports */
576 typec_altmode_set_partner(alt
);
578 /* The partners are bind to drivers */
579 if (is_typec_partner(parent
))
580 alt
->adev
.dev
.bus
= &typec_bus
;
582 /* Plug alt modes need a class to generate udev events. */
583 if (is_typec_plug(parent
))
584 alt
->adev
.dev
.class = &typec_class
;
586 ret
= device_register(&alt
->adev
.dev
);
588 dev_err(parent
, "failed to register alternate mode (%d)\n",
590 put_device(&alt
->adev
.dev
);
598 * typec_unregister_altmode - Unregister Alternate Mode
599 * @adev: The alternate mode to be unregistered
601 * Unregister device created with typec_partner_register_altmode(),
602 * typec_plug_register_altmode() or typec_port_register_altmode().
604 void typec_unregister_altmode(struct typec_altmode
*adev
)
606 if (IS_ERR_OR_NULL(adev
))
608 typec_retimer_put(to_altmode(adev
)->retimer
);
609 typec_mux_put(to_altmode(adev
)->mux
);
610 device_unregister(&adev
->dev
);
612 EXPORT_SYMBOL_GPL(typec_unregister_altmode
);
614 /* ------------------------------------------------------------------------- */
615 /* Type-C Partners */
617 static ssize_t
accessory_mode_show(struct device
*dev
,
618 struct device_attribute
*attr
,
621 struct typec_partner
*p
= to_typec_partner(dev
);
623 return sprintf(buf
, "%s\n", typec_accessory_modes
[p
->accessory
]);
625 static DEVICE_ATTR_RO(accessory_mode
);
627 static ssize_t
supports_usb_power_delivery_show(struct device
*dev
,
628 struct device_attribute
*attr
,
631 struct typec_partner
*p
= to_typec_partner(dev
);
633 return sprintf(buf
, "%s\n", p
->usb_pd
? "yes" : "no");
635 static DEVICE_ATTR_RO(supports_usb_power_delivery
);
637 static ssize_t
number_of_alternate_modes_show(struct device
*dev
, struct device_attribute
*attr
,
640 struct typec_partner
*partner
;
641 struct typec_plug
*plug
;
644 if (is_typec_partner(dev
)) {
645 partner
= to_typec_partner(dev
);
646 num_altmodes
= partner
->num_altmodes
;
647 } else if (is_typec_plug(dev
)) {
648 plug
= to_typec_plug(dev
);
649 num_altmodes
= plug
->num_altmodes
;
654 return sysfs_emit(buf
, "%d\n", num_altmodes
);
656 static DEVICE_ATTR_RO(number_of_alternate_modes
);
658 static struct attribute
*typec_partner_attrs
[] = {
659 &dev_attr_accessory_mode
.attr
,
660 &dev_attr_supports_usb_power_delivery
.attr
,
661 &dev_attr_number_of_alternate_modes
.attr
,
663 &dev_attr_usb_power_delivery_revision
.attr
,
667 static umode_t
typec_partner_attr_is_visible(struct kobject
*kobj
, struct attribute
*attr
, int n
)
669 struct typec_partner
*partner
= to_typec_partner(kobj_to_dev(kobj
));
671 if (attr
== &dev_attr_number_of_alternate_modes
.attr
) {
672 if (partner
->num_altmodes
< 0)
676 if (attr
== &dev_attr_type
.attr
)
677 if (!get_pd_product_type(kobj_to_dev(kobj
)))
683 static const struct attribute_group typec_partner_group
= {
684 .is_visible
= typec_partner_attr_is_visible
,
685 .attrs
= typec_partner_attrs
688 static const struct attribute_group
*typec_partner_groups
[] = {
689 &typec_partner_group
,
693 static void typec_partner_release(struct device
*dev
)
695 struct typec_partner
*partner
= to_typec_partner(dev
);
697 ida_destroy(&partner
->mode_ids
);
701 const struct device_type typec_partner_dev_type
= {
702 .name
= "typec_partner",
703 .groups
= typec_partner_groups
,
704 .release
= typec_partner_release
,
707 static void typec_partner_link_device(struct typec_partner
*partner
, struct device
*dev
)
711 ret
= sysfs_create_link(&dev
->kobj
, &partner
->dev
.kobj
, "typec");
715 ret
= sysfs_create_link(&partner
->dev
.kobj
, &dev
->kobj
, dev_name(dev
));
717 sysfs_remove_link(&dev
->kobj
, "typec");
722 partner
->attach(partner
, dev
);
725 static void typec_partner_unlink_device(struct typec_partner
*partner
, struct device
*dev
)
727 sysfs_remove_link(&partner
->dev
.kobj
, dev_name(dev
));
728 sysfs_remove_link(&dev
->kobj
, "typec");
730 if (partner
->deattach
)
731 partner
->deattach(partner
, dev
);
735 * typec_partner_set_identity - Report result from Discover Identity command
736 * @partner: The partner updated identity values
738 * This routine is used to report that the result of Discover Identity USB power
739 * delivery command has become available.
741 int typec_partner_set_identity(struct typec_partner
*partner
)
743 if (!partner
->identity
)
746 typec_report_identity(&partner
->dev
);
749 EXPORT_SYMBOL_GPL(typec_partner_set_identity
);
752 * typec_partner_set_pd_revision - Set the PD revision supported by the partner
753 * @partner: The partner to be updated.
754 * @pd_revision: USB Power Delivery Specification Revision supported by partner
756 * This routine is used to report that the PD revision of the port partner has
759 void typec_partner_set_pd_revision(struct typec_partner
*partner
, u16 pd_revision
)
761 if (partner
->pd_revision
== pd_revision
)
764 partner
->pd_revision
= pd_revision
;
765 sysfs_notify(&partner
->dev
.kobj
, NULL
, "usb_power_delivery_revision");
766 if (pd_revision
!= 0 && !partner
->usb_pd
) {
768 sysfs_notify(&partner
->dev
.kobj
, NULL
,
769 "supports_usb_power_delivery");
771 kobject_uevent(&partner
->dev
.kobj
, KOBJ_CHANGE
);
773 EXPORT_SYMBOL_GPL(typec_partner_set_pd_revision
);
776 * typec_partner_set_usb_power_delivery - Declare USB Power Delivery Contract.
777 * @partner: The partner device.
778 * @pd: The USB PD instance.
780 * This routine can be used to declare USB Power Delivery Contract with @partner
781 * by linking @partner to @pd which contains the objects that were used during the
782 * negotiation of the contract.
784 * If @pd is NULL, the link is removed and the contract with @partner has ended.
786 int typec_partner_set_usb_power_delivery(struct typec_partner
*partner
,
787 struct usb_power_delivery
*pd
)
791 if (IS_ERR_OR_NULL(partner
) || partner
->pd
== pd
)
795 ret
= usb_power_delivery_link_device(pd
, &partner
->dev
);
799 usb_power_delivery_unlink_device(partner
->pd
, &partner
->dev
);
806 EXPORT_SYMBOL_GPL(typec_partner_set_usb_power_delivery
);
809 * typec_partner_set_num_altmodes - Set the number of available partner altmodes
810 * @partner: The partner to be updated.
811 * @num_altmodes: The number of altmodes we want to specify as available.
813 * This routine is used to report the number of alternate modes supported by the
814 * partner. This value is *not* enforced in alternate mode registration routines.
816 * @partner.num_altmodes is set to -1 on partner registration, denoting that
817 * a valid value has not been set for it yet.
819 * Returns 0 on success or negative error number on failure.
821 int typec_partner_set_num_altmodes(struct typec_partner
*partner
, int num_altmodes
)
825 if (num_altmodes
< 0)
828 partner
->num_altmodes
= num_altmodes
;
829 ret
= sysfs_update_group(&partner
->dev
.kobj
, &typec_partner_group
);
833 sysfs_notify(&partner
->dev
.kobj
, NULL
, "number_of_alternate_modes");
834 kobject_uevent(&partner
->dev
.kobj
, KOBJ_CHANGE
);
838 EXPORT_SYMBOL_GPL(typec_partner_set_num_altmodes
);
841 * typec_partner_register_altmode - Register USB Type-C Partner Alternate Mode
842 * @partner: USB Type-C Partner that supports the alternate mode
843 * @desc: Description of the alternate mode
845 * This routine is used to register each alternate mode individually that
846 * @partner has listed in response to Discover SVIDs command. The modes for a
847 * SVID listed in response to Discover Modes command need to be listed in an
850 * Returns handle to the alternate mode on success or ERR_PTR on failure.
852 struct typec_altmode
*
853 typec_partner_register_altmode(struct typec_partner
*partner
,
854 const struct typec_altmode_desc
*desc
)
856 return typec_register_altmode(&partner
->dev
, desc
);
858 EXPORT_SYMBOL_GPL(typec_partner_register_altmode
);
861 * typec_partner_set_svdm_version - Set negotiated Structured VDM (SVDM) Version
862 * @partner: USB Type-C Partner that supports SVDM
863 * @svdm_version: Negotiated SVDM Version
865 * This routine is used to save the negotiated SVDM Version.
867 void typec_partner_set_svdm_version(struct typec_partner
*partner
,
868 enum usb_pd_svdm_ver svdm_version
)
870 partner
->svdm_version
= svdm_version
;
872 EXPORT_SYMBOL_GPL(typec_partner_set_svdm_version
);
875 * typec_partner_usb_power_delivery_register - Register Type-C partner USB Power Delivery Support
876 * @partner: Type-C partner device.
877 * @desc: Description of the USB PD contract.
879 * This routine is a wrapper around usb_power_delivery_register(). It registers
880 * USB Power Delivery Capabilities for a Type-C partner device. Specifically,
881 * it sets the Type-C partner device as a parent for the resulting USB Power Delivery object.
883 * Returns handle to struct usb_power_delivery or ERR_PTR.
885 struct usb_power_delivery
*
886 typec_partner_usb_power_delivery_register(struct typec_partner
*partner
,
887 struct usb_power_delivery_desc
*desc
)
889 return usb_power_delivery_register(&partner
->dev
, desc
);
891 EXPORT_SYMBOL_GPL(typec_partner_usb_power_delivery_register
);
894 * typec_register_partner - Register a USB Type-C Partner
895 * @port: The USB Type-C Port the partner is connected to
896 * @desc: Description of the partner
898 * Registers a device for USB Type-C Partner described in @desc.
900 * Returns handle to the partner on success or ERR_PTR on failure.
902 struct typec_partner
*typec_register_partner(struct typec_port
*port
,
903 struct typec_partner_desc
*desc
)
905 struct typec_partner
*partner
;
908 partner
= kzalloc(sizeof(*partner
), GFP_KERNEL
);
910 return ERR_PTR(-ENOMEM
);
912 ida_init(&partner
->mode_ids
);
913 partner
->usb_pd
= desc
->usb_pd
;
914 partner
->accessory
= desc
->accessory
;
915 partner
->num_altmodes
= -1;
916 partner
->pd_revision
= desc
->pd_revision
;
917 partner
->svdm_version
= port
->cap
->svdm_version
;
918 partner
->attach
= desc
->attach
;
919 partner
->deattach
= desc
->deattach
;
921 if (desc
->identity
) {
923 * Creating directory for the identity only if the driver is
924 * able to provide data to it.
926 partner
->dev
.groups
= usb_pd_id_groups
;
927 partner
->identity
= desc
->identity
;
930 partner
->dev
.class = &typec_class
;
931 partner
->dev
.parent
= &port
->dev
;
932 partner
->dev
.type
= &typec_partner_dev_type
;
933 dev_set_name(&partner
->dev
, "%s-partner", dev_name(&port
->dev
));
935 ret
= device_register(&partner
->dev
);
937 dev_err(&port
->dev
, "failed to register partner (%d)\n", ret
);
938 put_device(&partner
->dev
);
943 typec_partner_link_device(partner
, port
->usb2_dev
);
945 typec_partner_link_device(partner
, port
->usb3_dev
);
949 EXPORT_SYMBOL_GPL(typec_register_partner
);
952 * typec_unregister_partner - Unregister a USB Type-C Partner
953 * @partner: The partner to be unregistered
955 * Unregister device created with typec_register_partner().
957 void typec_unregister_partner(struct typec_partner
*partner
)
959 struct typec_port
*port
;
961 if (IS_ERR_OR_NULL(partner
))
964 port
= to_typec_port(partner
->dev
.parent
);
967 typec_partner_unlink_device(partner
, port
->usb2_dev
);
969 typec_partner_unlink_device(partner
, port
->usb3_dev
);
971 device_unregister(&partner
->dev
);
973 EXPORT_SYMBOL_GPL(typec_unregister_partner
);
975 /* ------------------------------------------------------------------------- */
976 /* Type-C Cable Plugs */
978 static void typec_plug_release(struct device
*dev
)
980 struct typec_plug
*plug
= to_typec_plug(dev
);
982 ida_destroy(&plug
->mode_ids
);
986 static struct attribute
*typec_plug_attrs
[] = {
987 &dev_attr_number_of_alternate_modes
.attr
,
991 static umode_t
typec_plug_attr_is_visible(struct kobject
*kobj
, struct attribute
*attr
, int n
)
993 struct typec_plug
*plug
= to_typec_plug(kobj_to_dev(kobj
));
995 if (attr
== &dev_attr_number_of_alternate_modes
.attr
) {
996 if (plug
->num_altmodes
< 0)
1003 static const struct attribute_group typec_plug_group
= {
1004 .is_visible
= typec_plug_attr_is_visible
,
1005 .attrs
= typec_plug_attrs
1008 static const struct attribute_group
*typec_plug_groups
[] = {
1013 const struct device_type typec_plug_dev_type
= {
1014 .name
= "typec_plug",
1015 .groups
= typec_plug_groups
,
1016 .release
= typec_plug_release
,
1020 * typec_plug_set_num_altmodes - Set the number of available plug altmodes
1021 * @plug: The plug to be updated.
1022 * @num_altmodes: The number of altmodes we want to specify as available.
1024 * This routine is used to report the number of alternate modes supported by the
1025 * plug. This value is *not* enforced in alternate mode registration routines.
1027 * @plug.num_altmodes is set to -1 on plug registration, denoting that
1028 * a valid value has not been set for it yet.
1030 * Returns 0 on success or negative error number on failure.
1032 int typec_plug_set_num_altmodes(struct typec_plug
*plug
, int num_altmodes
)
1036 if (num_altmodes
< 0)
1039 plug
->num_altmodes
= num_altmodes
;
1040 ret
= sysfs_update_group(&plug
->dev
.kobj
, &typec_plug_group
);
1044 sysfs_notify(&plug
->dev
.kobj
, NULL
, "number_of_alternate_modes");
1045 kobject_uevent(&plug
->dev
.kobj
, KOBJ_CHANGE
);
1049 EXPORT_SYMBOL_GPL(typec_plug_set_num_altmodes
);
1052 * typec_plug_register_altmode - Register USB Type-C Cable Plug Alternate Mode
1053 * @plug: USB Type-C Cable Plug that supports the alternate mode
1054 * @desc: Description of the alternate mode
1056 * This routine is used to register each alternate mode individually that @plug
1057 * has listed in response to Discover SVIDs command. The modes for a SVID that
1058 * the plug lists in response to Discover Modes command need to be listed in an
1061 * Returns handle to the alternate mode on success or ERR_PTR on failure.
1063 struct typec_altmode
*
1064 typec_plug_register_altmode(struct typec_plug
*plug
,
1065 const struct typec_altmode_desc
*desc
)
1067 return typec_register_altmode(&plug
->dev
, desc
);
1069 EXPORT_SYMBOL_GPL(typec_plug_register_altmode
);
1072 * typec_register_plug - Register a USB Type-C Cable Plug
1073 * @cable: USB Type-C Cable with the plug
1074 * @desc: Description of the cable plug
1076 * Registers a device for USB Type-C Cable Plug described in @desc. A USB Type-C
1077 * Cable Plug represents a plug with electronics in it that can response to USB
1078 * Power Delivery SOP Prime or SOP Double Prime packages.
1080 * Returns handle to the cable plug on success or ERR_PTR on failure.
1082 struct typec_plug
*typec_register_plug(struct typec_cable
*cable
,
1083 struct typec_plug_desc
*desc
)
1085 struct typec_plug
*plug
;
1089 plug
= kzalloc(sizeof(*plug
), GFP_KERNEL
);
1091 return ERR_PTR(-ENOMEM
);
1093 sprintf(name
, "plug%d", desc
->index
);
1095 ida_init(&plug
->mode_ids
);
1096 plug
->num_altmodes
= -1;
1097 plug
->index
= desc
->index
;
1098 plug
->dev
.class = &typec_class
;
1099 plug
->dev
.parent
= &cable
->dev
;
1100 plug
->dev
.type
= &typec_plug_dev_type
;
1101 dev_set_name(&plug
->dev
, "%s-%s", dev_name(cable
->dev
.parent
), name
);
1103 ret
= device_register(&plug
->dev
);
1105 dev_err(&cable
->dev
, "failed to register plug (%d)\n", ret
);
1106 put_device(&plug
->dev
);
1107 return ERR_PTR(ret
);
1112 EXPORT_SYMBOL_GPL(typec_register_plug
);
1115 * typec_unregister_plug - Unregister a USB Type-C Cable Plug
1116 * @plug: The cable plug to be unregistered
1118 * Unregister device created with typec_register_plug().
1120 void typec_unregister_plug(struct typec_plug
*plug
)
1122 if (!IS_ERR_OR_NULL(plug
))
1123 device_unregister(&plug
->dev
);
1125 EXPORT_SYMBOL_GPL(typec_unregister_plug
);
1129 static const char * const typec_plug_types
[] = {
1130 [USB_PLUG_NONE
] = "unknown",
1131 [USB_PLUG_TYPE_A
] = "type-a",
1132 [USB_PLUG_TYPE_B
] = "type-b",
1133 [USB_PLUG_TYPE_C
] = "type-c",
1134 [USB_PLUG_CAPTIVE
] = "captive",
1137 static ssize_t
plug_type_show(struct device
*dev
,
1138 struct device_attribute
*attr
, char *buf
)
1140 struct typec_cable
*cable
= to_typec_cable(dev
);
1142 return sprintf(buf
, "%s\n", typec_plug_types
[cable
->type
]);
1144 static DEVICE_ATTR_RO(plug_type
);
1146 static struct attribute
*typec_cable_attrs
[] = {
1147 &dev_attr_type
.attr
,
1148 &dev_attr_plug_type
.attr
,
1149 &dev_attr_usb_power_delivery_revision
.attr
,
1152 ATTRIBUTE_GROUPS(typec_cable
);
1154 static void typec_cable_release(struct device
*dev
)
1156 struct typec_cable
*cable
= to_typec_cable(dev
);
1161 const struct device_type typec_cable_dev_type
= {
1162 .name
= "typec_cable",
1163 .groups
= typec_cable_groups
,
1164 .release
= typec_cable_release
,
1167 static int cable_match(struct device
*dev
, void *data
)
1169 return is_typec_cable(dev
);
1173 * typec_cable_get - Get a reference to the USB Type-C cable
1174 * @port: The USB Type-C Port the cable is connected to
1176 * The caller must decrement the reference count with typec_cable_put() after
1179 struct typec_cable
*typec_cable_get(struct typec_port
*port
)
1183 dev
= device_find_child(&port
->dev
, NULL
, cable_match
);
1187 return to_typec_cable(dev
);
1189 EXPORT_SYMBOL_GPL(typec_cable_get
);
1192 * typec_cable_put - Decrement the reference count on USB Type-C cable
1193 * @cable: The USB Type-C cable
1195 void typec_cable_put(struct typec_cable
*cable
)
1197 put_device(&cable
->dev
);
1199 EXPORT_SYMBOL_GPL(typec_cable_put
);
1202 * typec_cable_is_active - Check is the USB Type-C cable active or passive
1203 * @cable: The USB Type-C Cable
1205 * Return 1 if the cable is active or 0 if it's passive.
1207 int typec_cable_is_active(struct typec_cable
*cable
)
1209 return cable
->active
;
1211 EXPORT_SYMBOL_GPL(typec_cable_is_active
);
1214 * typec_cable_set_identity - Report result from Discover Identity command
1215 * @cable: The cable updated identity values
1217 * This routine is used to report that the result of Discover Identity USB power
1218 * delivery command has become available.
1220 int typec_cable_set_identity(struct typec_cable
*cable
)
1222 if (!cable
->identity
)
1225 typec_report_identity(&cable
->dev
);
1228 EXPORT_SYMBOL_GPL(typec_cable_set_identity
);
1231 * typec_register_cable - Register a USB Type-C Cable
1232 * @port: The USB Type-C Port the cable is connected to
1233 * @desc: Description of the cable
1235 * Registers a device for USB Type-C Cable described in @desc. The cable will be
1236 * parent for the optional cable plug devises.
1238 * Returns handle to the cable on success or ERR_PTR on failure.
1240 struct typec_cable
*typec_register_cable(struct typec_port
*port
,
1241 struct typec_cable_desc
*desc
)
1243 struct typec_cable
*cable
;
1246 cable
= kzalloc(sizeof(*cable
), GFP_KERNEL
);
1248 return ERR_PTR(-ENOMEM
);
1250 cable
->type
= desc
->type
;
1251 cable
->active
= desc
->active
;
1252 cable
->pd_revision
= desc
->pd_revision
;
1254 if (desc
->identity
) {
1256 * Creating directory for the identity only if the driver is
1257 * able to provide data to it.
1259 cable
->dev
.groups
= usb_pd_id_groups
;
1260 cable
->identity
= desc
->identity
;
1263 cable
->dev
.class = &typec_class
;
1264 cable
->dev
.parent
= &port
->dev
;
1265 cable
->dev
.type
= &typec_cable_dev_type
;
1266 dev_set_name(&cable
->dev
, "%s-cable", dev_name(&port
->dev
));
1268 ret
= device_register(&cable
->dev
);
1270 dev_err(&port
->dev
, "failed to register cable (%d)\n", ret
);
1271 put_device(&cable
->dev
);
1272 return ERR_PTR(ret
);
1277 EXPORT_SYMBOL_GPL(typec_register_cable
);
1280 * typec_unregister_cable - Unregister a USB Type-C Cable
1281 * @cable: The cable to be unregistered
1283 * Unregister device created with typec_register_cable().
1285 void typec_unregister_cable(struct typec_cable
*cable
)
1287 if (!IS_ERR_OR_NULL(cable
))
1288 device_unregister(&cable
->dev
);
1290 EXPORT_SYMBOL_GPL(typec_unregister_cable
);
1292 /* ------------------------------------------------------------------------- */
1293 /* USB Type-C ports */
1296 * typec_port_set_usb_power_delivery - Assign USB PD for port.
1297 * @port: USB Type-C port.
1298 * @pd: USB PD instance.
1300 * This routine can be used to set the USB Power Delivery Capabilities for @port
1301 * that it will advertise to the partner.
1303 * If @pd is NULL, the assignment is removed.
1305 int typec_port_set_usb_power_delivery(struct typec_port
*port
, struct usb_power_delivery
*pd
)
1309 if (IS_ERR_OR_NULL(port
) || port
->pd
== pd
)
1313 ret
= usb_power_delivery_link_device(pd
, &port
->dev
);
1317 usb_power_delivery_unlink_device(port
->pd
, &port
->dev
);
1324 EXPORT_SYMBOL_GPL(typec_port_set_usb_power_delivery
);
1326 static ssize_t
select_usb_power_delivery_store(struct device
*dev
,
1327 struct device_attribute
*attr
,
1328 const char *buf
, size_t size
)
1330 struct typec_port
*port
= to_typec_port(dev
);
1331 struct usb_power_delivery
*pd
;
1334 if (!port
->ops
|| !port
->ops
->pd_set
)
1337 pd
= usb_power_delivery_find(buf
);
1341 ret
= port
->ops
->pd_set(port
, pd
);
1348 static ssize_t
select_usb_power_delivery_show(struct device
*dev
,
1349 struct device_attribute
*attr
, char *buf
)
1351 struct typec_port
*port
= to_typec_port(dev
);
1352 struct usb_power_delivery
**pds
;
1355 if (!port
->ops
|| !port
->ops
->pd_get
)
1358 pds
= port
->ops
->pd_get(port
);
1362 for (i
= 0; pds
[i
]; i
++) {
1363 if (pds
[i
] == port
->pd
)
1364 ret
+= sysfs_emit_at(buf
, ret
, "[%s] ", dev_name(&pds
[i
]->dev
));
1366 ret
+= sysfs_emit_at(buf
, ret
, "%s ", dev_name(&pds
[i
]->dev
));
1369 buf
[ret
- 1] = '\n';
1373 static DEVICE_ATTR_RW(select_usb_power_delivery
);
1375 static struct attribute
*port_attrs
[] = {
1376 &dev_attr_select_usb_power_delivery
.attr
,
1380 static umode_t
port_attr_is_visible(struct kobject
*kobj
, struct attribute
*attr
, int n
)
1382 struct typec_port
*port
= to_typec_port(kobj_to_dev(kobj
));
1384 if (!port
->pd
|| !port
->ops
|| !port
->ops
->pd_get
)
1386 if (!port
->ops
->pd_set
)
1392 static const struct attribute_group pd_group
= {
1393 .is_visible
= port_attr_is_visible
,
1394 .attrs
= port_attrs
,
1397 static const char * const typec_orientations
[] = {
1398 [TYPEC_ORIENTATION_NONE
] = "unknown",
1399 [TYPEC_ORIENTATION_NORMAL
] = "normal",
1400 [TYPEC_ORIENTATION_REVERSE
] = "reverse",
1403 static const char * const typec_roles
[] = {
1404 [TYPEC_SINK
] = "sink",
1405 [TYPEC_SOURCE
] = "source",
1408 static const char * const typec_data_roles
[] = {
1409 [TYPEC_DEVICE
] = "device",
1410 [TYPEC_HOST
] = "host",
1413 static const char * const typec_port_power_roles
[] = {
1414 [TYPEC_PORT_SRC
] = "source",
1415 [TYPEC_PORT_SNK
] = "sink",
1416 [TYPEC_PORT_DRP
] = "dual",
1419 static const char * const typec_port_data_roles
[] = {
1420 [TYPEC_PORT_DFP
] = "host",
1421 [TYPEC_PORT_UFP
] = "device",
1422 [TYPEC_PORT_DRD
] = "dual",
1425 static const char * const typec_port_types_drp
[] = {
1426 [TYPEC_PORT_SRC
] = "dual [source] sink",
1427 [TYPEC_PORT_SNK
] = "dual source [sink]",
1428 [TYPEC_PORT_DRP
] = "[dual] source sink",
1432 preferred_role_store(struct device
*dev
, struct device_attribute
*attr
,
1433 const char *buf
, size_t size
)
1435 struct typec_port
*port
= to_typec_port(dev
);
1439 if (port
->cap
->type
!= TYPEC_PORT_DRP
) {
1440 dev_dbg(dev
, "Preferred role only supported with DRP ports\n");
1444 if (!port
->ops
|| !port
->ops
->try_role
) {
1445 dev_dbg(dev
, "Setting preferred role not supported\n");
1449 role
= sysfs_match_string(typec_roles
, buf
);
1451 if (sysfs_streq(buf
, "none"))
1452 role
= TYPEC_NO_PREFERRED_ROLE
;
1457 ret
= port
->ops
->try_role(port
, role
);
1461 port
->prefer_role
= role
;
1466 preferred_role_show(struct device
*dev
, struct device_attribute
*attr
,
1469 struct typec_port
*port
= to_typec_port(dev
);
1471 if (port
->cap
->type
!= TYPEC_PORT_DRP
)
1474 if (port
->prefer_role
< 0)
1477 return sprintf(buf
, "%s\n", typec_roles
[port
->prefer_role
]);
1479 static DEVICE_ATTR_RW(preferred_role
);
1481 static ssize_t
data_role_store(struct device
*dev
,
1482 struct device_attribute
*attr
,
1483 const char *buf
, size_t size
)
1485 struct typec_port
*port
= to_typec_port(dev
);
1488 if (!port
->ops
|| !port
->ops
->dr_set
) {
1489 dev_dbg(dev
, "data role swapping not supported\n");
1493 ret
= sysfs_match_string(typec_data_roles
, buf
);
1497 mutex_lock(&port
->port_type_lock
);
1498 if (port
->cap
->data
!= TYPEC_PORT_DRD
) {
1500 goto unlock_and_ret
;
1503 ret
= port
->ops
->dr_set(port
, ret
);
1505 goto unlock_and_ret
;
1509 mutex_unlock(&port
->port_type_lock
);
1513 static ssize_t
data_role_show(struct device
*dev
,
1514 struct device_attribute
*attr
, char *buf
)
1516 struct typec_port
*port
= to_typec_port(dev
);
1518 if (port
->cap
->data
== TYPEC_PORT_DRD
)
1519 return sprintf(buf
, "%s\n", port
->data_role
== TYPEC_HOST
?
1520 "[host] device" : "host [device]");
1522 return sprintf(buf
, "[%s]\n", typec_data_roles
[port
->data_role
]);
1524 static DEVICE_ATTR_RW(data_role
);
1526 static ssize_t
power_role_store(struct device
*dev
,
1527 struct device_attribute
*attr
,
1528 const char *buf
, size_t size
)
1530 struct typec_port
*port
= to_typec_port(dev
);
1533 if (!port
->ops
|| !port
->ops
->pr_set
) {
1534 dev_dbg(dev
, "power role swapping not supported\n");
1538 if (port
->pwr_opmode
!= TYPEC_PWR_MODE_PD
) {
1539 dev_dbg(dev
, "partner unable to swap power role\n");
1543 ret
= sysfs_match_string(typec_roles
, buf
);
1547 mutex_lock(&port
->port_type_lock
);
1548 if (port
->port_type
!= TYPEC_PORT_DRP
) {
1549 dev_dbg(dev
, "port type fixed at \"%s\"",
1550 typec_port_power_roles
[port
->port_type
]);
1552 goto unlock_and_ret
;
1555 ret
= port
->ops
->pr_set(port
, ret
);
1557 goto unlock_and_ret
;
1561 mutex_unlock(&port
->port_type_lock
);
1565 static ssize_t
power_role_show(struct device
*dev
,
1566 struct device_attribute
*attr
, char *buf
)
1568 struct typec_port
*port
= to_typec_port(dev
);
1570 if (port
->cap
->type
== TYPEC_PORT_DRP
)
1571 return sprintf(buf
, "%s\n", port
->pwr_role
== TYPEC_SOURCE
?
1572 "[source] sink" : "source [sink]");
1574 return sprintf(buf
, "[%s]\n", typec_roles
[port
->pwr_role
]);
1576 static DEVICE_ATTR_RW(power_role
);
1579 port_type_store(struct device
*dev
, struct device_attribute
*attr
,
1580 const char *buf
, size_t size
)
1582 struct typec_port
*port
= to_typec_port(dev
);
1584 enum typec_port_type type
;
1586 if (port
->cap
->type
!= TYPEC_PORT_DRP
||
1587 !port
->ops
|| !port
->ops
->port_type_set
) {
1588 dev_dbg(dev
, "changing port type not supported\n");
1592 ret
= sysfs_match_string(typec_port_power_roles
, buf
);
1597 mutex_lock(&port
->port_type_lock
);
1599 if (port
->port_type
== type
) {
1601 goto unlock_and_ret
;
1604 ret
= port
->ops
->port_type_set(port
, type
);
1606 goto unlock_and_ret
;
1608 port
->port_type
= type
;
1612 mutex_unlock(&port
->port_type_lock
);
1617 port_type_show(struct device
*dev
, struct device_attribute
*attr
,
1620 struct typec_port
*port
= to_typec_port(dev
);
1622 if (port
->cap
->type
== TYPEC_PORT_DRP
)
1623 return sprintf(buf
, "%s\n",
1624 typec_port_types_drp
[port
->port_type
]);
1626 return sprintf(buf
, "[%s]\n", typec_port_power_roles
[port
->cap
->type
]);
1628 static DEVICE_ATTR_RW(port_type
);
1630 static const char * const typec_pwr_opmodes
[] = {
1631 [TYPEC_PWR_MODE_USB
] = "default",
1632 [TYPEC_PWR_MODE_1_5A
] = "1.5A",
1633 [TYPEC_PWR_MODE_3_0A
] = "3.0A",
1634 [TYPEC_PWR_MODE_PD
] = "usb_power_delivery",
1637 static ssize_t
power_operation_mode_show(struct device
*dev
,
1638 struct device_attribute
*attr
,
1641 struct typec_port
*port
= to_typec_port(dev
);
1643 return sprintf(buf
, "%s\n", typec_pwr_opmodes
[port
->pwr_opmode
]);
1645 static DEVICE_ATTR_RO(power_operation_mode
);
1647 static ssize_t
vconn_source_store(struct device
*dev
,
1648 struct device_attribute
*attr
,
1649 const char *buf
, size_t size
)
1651 struct typec_port
*port
= to_typec_port(dev
);
1655 if (!port
->cap
->pd_revision
) {
1656 dev_dbg(dev
, "VCONN swap depends on USB Power Delivery\n");
1660 if (!port
->ops
|| !port
->ops
->vconn_set
) {
1661 dev_dbg(dev
, "VCONN swapping not supported\n");
1665 ret
= kstrtobool(buf
, &source
);
1669 ret
= port
->ops
->vconn_set(port
, (enum typec_role
)source
);
1676 static ssize_t
vconn_source_show(struct device
*dev
,
1677 struct device_attribute
*attr
, char *buf
)
1679 struct typec_port
*port
= to_typec_port(dev
);
1681 return sprintf(buf
, "%s\n",
1682 port
->vconn_role
== TYPEC_SOURCE
? "yes" : "no");
1684 static DEVICE_ATTR_RW(vconn_source
);
1686 static ssize_t
supported_accessory_modes_show(struct device
*dev
,
1687 struct device_attribute
*attr
,
1690 struct typec_port
*port
= to_typec_port(dev
);
1694 for (i
= 0; i
< ARRAY_SIZE(port
->cap
->accessory
); i
++) {
1695 if (port
->cap
->accessory
[i
])
1696 ret
+= sprintf(buf
+ ret
, "%s ",
1697 typec_accessory_modes
[port
->cap
->accessory
[i
]]);
1701 return sprintf(buf
, "none\n");
1703 buf
[ret
- 1] = '\n';
1707 static DEVICE_ATTR_RO(supported_accessory_modes
);
1709 static ssize_t
usb_typec_revision_show(struct device
*dev
,
1710 struct device_attribute
*attr
,
1713 struct typec_port
*port
= to_typec_port(dev
);
1714 u16 rev
= port
->cap
->revision
;
1716 return sprintf(buf
, "%d.%d\n", (rev
>> 8) & 0xff, (rev
>> 4) & 0xf);
1718 static DEVICE_ATTR_RO(usb_typec_revision
);
1720 static ssize_t
usb_power_delivery_revision_show(struct device
*dev
,
1721 struct device_attribute
*attr
,
1726 if (is_typec_partner(dev
)) {
1727 struct typec_partner
*partner
= to_typec_partner(dev
);
1729 rev
= partner
->pd_revision
;
1730 } else if (is_typec_cable(dev
)) {
1731 struct typec_cable
*cable
= to_typec_cable(dev
);
1733 rev
= cable
->pd_revision
;
1734 } else if (is_typec_port(dev
)) {
1735 struct typec_port
*p
= to_typec_port(dev
);
1737 rev
= p
->cap
->pd_revision
;
1739 return sysfs_emit(buf
, "%d.%d\n", (rev
>> 8) & 0xff, (rev
>> 4) & 0xf);
1742 static ssize_t
orientation_show(struct device
*dev
,
1743 struct device_attribute
*attr
,
1746 struct typec_port
*port
= to_typec_port(dev
);
1748 return sprintf(buf
, "%s\n", typec_orientations
[port
->orientation
]);
1750 static DEVICE_ATTR_RO(orientation
);
1752 static struct attribute
*typec_attrs
[] = {
1753 &dev_attr_data_role
.attr
,
1754 &dev_attr_power_operation_mode
.attr
,
1755 &dev_attr_power_role
.attr
,
1756 &dev_attr_preferred_role
.attr
,
1757 &dev_attr_supported_accessory_modes
.attr
,
1758 &dev_attr_usb_power_delivery_revision
.attr
,
1759 &dev_attr_usb_typec_revision
.attr
,
1760 &dev_attr_vconn_source
.attr
,
1761 &dev_attr_port_type
.attr
,
1762 &dev_attr_orientation
.attr
,
1766 static umode_t
typec_attr_is_visible(struct kobject
*kobj
,
1767 struct attribute
*attr
, int n
)
1769 struct typec_port
*port
= to_typec_port(kobj_to_dev(kobj
));
1771 if (attr
== &dev_attr_data_role
.attr
) {
1772 if (port
->cap
->data
!= TYPEC_PORT_DRD
||
1773 !port
->ops
|| !port
->ops
->dr_set
)
1775 } else if (attr
== &dev_attr_power_role
.attr
) {
1776 if (port
->cap
->type
!= TYPEC_PORT_DRP
||
1777 !port
->ops
|| !port
->ops
->pr_set
)
1779 } else if (attr
== &dev_attr_vconn_source
.attr
) {
1780 if (!port
->cap
->pd_revision
||
1781 !port
->ops
|| !port
->ops
->vconn_set
)
1783 } else if (attr
== &dev_attr_preferred_role
.attr
) {
1784 if (port
->cap
->type
!= TYPEC_PORT_DRP
||
1785 !port
->ops
|| !port
->ops
->try_role
)
1787 } else if (attr
== &dev_attr_port_type
.attr
) {
1788 if (!port
->ops
|| !port
->ops
->port_type_set
)
1790 if (port
->cap
->type
!= TYPEC_PORT_DRP
)
1792 } else if (attr
== &dev_attr_orientation
.attr
) {
1793 if (port
->cap
->orientation_aware
)
1801 static const struct attribute_group typec_group
= {
1802 .is_visible
= typec_attr_is_visible
,
1803 .attrs
= typec_attrs
,
1806 static const struct attribute_group
*typec_groups
[] = {
1812 static int typec_uevent(const struct device
*dev
, struct kobj_uevent_env
*env
)
1816 ret
= add_uevent_var(env
, "TYPEC_PORT=%s", dev_name(dev
));
1818 dev_err(dev
, "failed to add uevent TYPEC_PORT\n");
1823 static void typec_release(struct device
*dev
)
1825 struct typec_port
*port
= to_typec_port(dev
);
1827 ida_free(&typec_index_ida
, port
->id
);
1828 ida_destroy(&port
->mode_ids
);
1829 typec_switch_put(port
->sw
);
1830 typec_mux_put(port
->mux
);
1831 typec_retimer_put(port
->retimer
);
1836 const struct device_type typec_port_dev_type
= {
1837 .name
= "typec_port",
1838 .groups
= typec_groups
,
1839 .uevent
= typec_uevent
,
1840 .release
= typec_release
,
1843 /* --------------------------------------- */
1844 /* Driver callbacks to report role updates */
1846 static int partner_match(struct device
*dev
, void *data
)
1848 return is_typec_partner(dev
);
1851 static struct typec_partner
*typec_get_partner(struct typec_port
*port
)
1855 dev
= device_find_child(&port
->dev
, NULL
, partner_match
);
1859 return to_typec_partner(dev
);
1862 static void typec_partner_attach(struct typec_connector
*con
, struct device
*dev
)
1864 struct typec_port
*port
= container_of(con
, struct typec_port
, con
);
1865 struct typec_partner
*partner
= typec_get_partner(port
);
1866 struct usb_device
*udev
= to_usb_device(dev
);
1868 if (udev
->speed
< USB_SPEED_SUPER
)
1869 port
->usb2_dev
= dev
;
1871 port
->usb3_dev
= dev
;
1874 typec_partner_link_device(partner
, dev
);
1875 put_device(&partner
->dev
);
1879 static void typec_partner_deattach(struct typec_connector
*con
, struct device
*dev
)
1881 struct typec_port
*port
= container_of(con
, struct typec_port
, con
);
1882 struct typec_partner
*partner
= typec_get_partner(port
);
1885 typec_partner_unlink_device(partner
, dev
);
1886 put_device(&partner
->dev
);
1889 if (port
->usb2_dev
== dev
)
1890 port
->usb2_dev
= NULL
;
1891 else if (port
->usb3_dev
== dev
)
1892 port
->usb3_dev
= NULL
;
1896 * typec_set_data_role - Report data role change
1897 * @port: The USB Type-C Port where the role was changed
1898 * @role: The new data role
1900 * This routine is used by the port drivers to report data role changes.
1902 void typec_set_data_role(struct typec_port
*port
, enum typec_data_role role
)
1904 struct typec_partner
*partner
;
1906 if (port
->data_role
== role
)
1909 port
->data_role
= role
;
1910 sysfs_notify(&port
->dev
.kobj
, NULL
, "data_role");
1911 kobject_uevent(&port
->dev
.kobj
, KOBJ_CHANGE
);
1913 partner
= typec_get_partner(port
);
1917 if (partner
->identity
)
1918 typec_product_type_notify(&partner
->dev
);
1920 put_device(&partner
->dev
);
1922 EXPORT_SYMBOL_GPL(typec_set_data_role
);
1925 * typec_set_pwr_role - Report power role change
1926 * @port: The USB Type-C Port where the role was changed
1927 * @role: The new data role
1929 * This routine is used by the port drivers to report power role changes.
1931 void typec_set_pwr_role(struct typec_port
*port
, enum typec_role role
)
1933 if (port
->pwr_role
== role
)
1936 port
->pwr_role
= role
;
1937 sysfs_notify(&port
->dev
.kobj
, NULL
, "power_role");
1938 kobject_uevent(&port
->dev
.kobj
, KOBJ_CHANGE
);
1940 EXPORT_SYMBOL_GPL(typec_set_pwr_role
);
1943 * typec_set_vconn_role - Report VCONN source change
1944 * @port: The USB Type-C Port which VCONN role changed
1945 * @role: Source when @port is sourcing VCONN, or Sink when it's not
1947 * This routine is used by the port drivers to report if the VCONN source is
1950 void typec_set_vconn_role(struct typec_port
*port
, enum typec_role role
)
1952 if (port
->vconn_role
== role
)
1955 port
->vconn_role
= role
;
1956 sysfs_notify(&port
->dev
.kobj
, NULL
, "vconn_source");
1957 kobject_uevent(&port
->dev
.kobj
, KOBJ_CHANGE
);
1959 EXPORT_SYMBOL_GPL(typec_set_vconn_role
);
1962 * typec_set_pwr_opmode - Report changed power operation mode
1963 * @port: The USB Type-C Port where the mode was changed
1964 * @opmode: New power operation mode
1966 * This routine is used by the port drivers to report changed power operation
1967 * mode in @port. The modes are USB (default), 1.5A, 3.0A as defined in USB
1968 * Type-C specification, and "USB Power Delivery" when the power levels are
1969 * negotiated with methods defined in USB Power Delivery specification.
1971 void typec_set_pwr_opmode(struct typec_port
*port
,
1972 enum typec_pwr_opmode opmode
)
1974 struct device
*partner_dev
;
1976 if (port
->pwr_opmode
== opmode
)
1979 port
->pwr_opmode
= opmode
;
1980 sysfs_notify(&port
->dev
.kobj
, NULL
, "power_operation_mode");
1981 kobject_uevent(&port
->dev
.kobj
, KOBJ_CHANGE
);
1983 partner_dev
= device_find_child(&port
->dev
, NULL
, partner_match
);
1985 struct typec_partner
*partner
= to_typec_partner(partner_dev
);
1987 if (opmode
== TYPEC_PWR_MODE_PD
&& !partner
->usb_pd
) {
1988 partner
->usb_pd
= 1;
1989 sysfs_notify(&partner_dev
->kobj
, NULL
,
1990 "supports_usb_power_delivery");
1991 kobject_uevent(&partner_dev
->kobj
, KOBJ_CHANGE
);
1993 put_device(partner_dev
);
1996 EXPORT_SYMBOL_GPL(typec_set_pwr_opmode
);
1999 * typec_find_pwr_opmode - Get the typec power operation mode capability
2000 * @name: power operation mode string
2002 * This routine is used to find the typec_pwr_opmode by its string @name.
2004 * Returns typec_pwr_opmode if success, otherwise negative error code.
2006 int typec_find_pwr_opmode(const char *name
)
2008 return match_string(typec_pwr_opmodes
,
2009 ARRAY_SIZE(typec_pwr_opmodes
), name
);
2011 EXPORT_SYMBOL_GPL(typec_find_pwr_opmode
);
2014 * typec_find_orientation - Convert orientation string to enum typec_orientation
2015 * @name: Orientation string
2017 * This routine is used to find the typec_orientation by its string name @name.
2019 * Returns the orientation value on success, otherwise negative error code.
2021 int typec_find_orientation(const char *name
)
2023 return match_string(typec_orientations
, ARRAY_SIZE(typec_orientations
),
2026 EXPORT_SYMBOL_GPL(typec_find_orientation
);
2029 * typec_find_port_power_role - Get the typec port power capability
2030 * @name: port power capability string
2032 * This routine is used to find the typec_port_type by its string name.
2034 * Returns typec_port_type if success, otherwise negative error code.
2036 int typec_find_port_power_role(const char *name
)
2038 return match_string(typec_port_power_roles
,
2039 ARRAY_SIZE(typec_port_power_roles
), name
);
2041 EXPORT_SYMBOL_GPL(typec_find_port_power_role
);
2044 * typec_find_power_role - Find the typec one specific power role
2045 * @name: power role string
2047 * This routine is used to find the typec_role by its string name.
2049 * Returns typec_role if success, otherwise negative error code.
2051 int typec_find_power_role(const char *name
)
2053 return match_string(typec_roles
, ARRAY_SIZE(typec_roles
), name
);
2055 EXPORT_SYMBOL_GPL(typec_find_power_role
);
2058 * typec_find_port_data_role - Get the typec port data capability
2059 * @name: port data capability string
2061 * This routine is used to find the typec_port_data by its string name.
2063 * Returns typec_port_data if success, otherwise negative error code.
2065 int typec_find_port_data_role(const char *name
)
2067 return match_string(typec_port_data_roles
,
2068 ARRAY_SIZE(typec_port_data_roles
), name
);
2070 EXPORT_SYMBOL_GPL(typec_find_port_data_role
);
2072 /* ------------------------------------------ */
2073 /* API for Multiplexer/DeMultiplexer Switches */
2076 * typec_set_orientation - Set USB Type-C cable plug orientation
2077 * @port: USB Type-C Port
2078 * @orientation: USB Type-C cable plug orientation
2080 * Set cable plug orientation for @port.
2082 int typec_set_orientation(struct typec_port
*port
,
2083 enum typec_orientation orientation
)
2087 ret
= typec_switch_set(port
->sw
, orientation
);
2091 port
->orientation
= orientation
;
2092 sysfs_notify(&port
->dev
.kobj
, NULL
, "orientation");
2093 kobject_uevent(&port
->dev
.kobj
, KOBJ_CHANGE
);
2097 EXPORT_SYMBOL_GPL(typec_set_orientation
);
2100 * typec_get_orientation - Get USB Type-C cable plug orientation
2101 * @port: USB Type-C Port
2103 * Get current cable plug orientation for @port.
2105 enum typec_orientation
typec_get_orientation(struct typec_port
*port
)
2107 return port
->orientation
;
2109 EXPORT_SYMBOL_GPL(typec_get_orientation
);
2112 * typec_set_mode - Set mode of operation for USB Type-C connector
2113 * @port: USB Type-C connector
2114 * @mode: Accessory Mode, USB Operation or Safe State
2116 * Configure @port for Accessory Mode @mode. This function will configure the
2117 * muxes needed for @mode.
2119 int typec_set_mode(struct typec_port
*port
, int mode
)
2121 struct typec_mux_state state
= { };
2125 return typec_mux_set(port
->mux
, &state
);
2127 EXPORT_SYMBOL_GPL(typec_set_mode
);
2129 /* --------------------------------------- */
2132 * typec_get_negotiated_svdm_version - Get negotiated SVDM Version
2133 * @port: USB Type-C Port.
2135 * Get the negotiated SVDM Version. The Version is set to the port default
2136 * value stored in typec_capability on partner registration, and updated after
2137 * a successful Discover Identity if the negotiated value is less than the
2140 * Returns usb_pd_svdm_ver if the partner has been registered otherwise -ENODEV.
2142 int typec_get_negotiated_svdm_version(struct typec_port
*port
)
2144 enum usb_pd_svdm_ver svdm_version
;
2145 struct device
*partner_dev
;
2147 partner_dev
= device_find_child(&port
->dev
, NULL
, partner_match
);
2151 svdm_version
= to_typec_partner(partner_dev
)->svdm_version
;
2152 put_device(partner_dev
);
2154 return svdm_version
;
2156 EXPORT_SYMBOL_GPL(typec_get_negotiated_svdm_version
);
2159 * typec_get_cable_svdm_version - Get cable negotiated SVDM Version
2160 * @port: USB Type-C Port.
2162 * Get the negotiated SVDM Version for the cable. The Version is set to the port
2163 * default value based on the PD Revision during cable registration, and updated
2164 * after a successful Discover Identity if the negotiated value is less than the
2167 * Returns usb_pd_svdm_ver if the cable has been registered otherwise -ENODEV.
2169 int typec_get_cable_svdm_version(struct typec_port
*port
)
2171 enum usb_pd_svdm_ver svdm_version
;
2172 struct device
*cable_dev
;
2174 cable_dev
= device_find_child(&port
->dev
, NULL
, cable_match
);
2178 svdm_version
= to_typec_cable(cable_dev
)->svdm_version
;
2179 put_device(cable_dev
);
2181 return svdm_version
;
2183 EXPORT_SYMBOL_GPL(typec_get_cable_svdm_version
);
2186 * typec_cable_set_svdm_version - Set negotiated Structured VDM (SVDM) Version
2187 * @cable: USB Type-C Active Cable that supports SVDM
2188 * @svdm_version: Negotiated SVDM Version
2190 * This routine is used to save the negotiated SVDM Version.
2192 void typec_cable_set_svdm_version(struct typec_cable
*cable
, enum usb_pd_svdm_ver svdm_version
)
2194 cable
->svdm_version
= svdm_version
;
2196 EXPORT_SYMBOL_GPL(typec_cable_set_svdm_version
);
2199 * typec_get_drvdata - Return private driver data pointer
2200 * @port: USB Type-C port
2202 void *typec_get_drvdata(struct typec_port
*port
)
2204 return dev_get_drvdata(&port
->dev
);
2206 EXPORT_SYMBOL_GPL(typec_get_drvdata
);
2208 int typec_get_fw_cap(struct typec_capability
*cap
,
2209 struct fwnode_handle
*fwnode
)
2211 const char *cap_str
;
2214 cap
->fwnode
= fwnode
;
2216 ret
= fwnode_property_read_string(fwnode
, "power-role", &cap_str
);
2220 ret
= typec_find_port_power_role(cap_str
);
2225 /* USB data support is optional */
2226 ret
= fwnode_property_read_string(fwnode
, "data-role", &cap_str
);
2228 ret
= typec_find_port_data_role(cap_str
);
2234 /* Get the preferred power role for a DRP */
2235 if (cap
->type
== TYPEC_PORT_DRP
) {
2236 cap
->prefer_role
= TYPEC_NO_PREFERRED_ROLE
;
2238 ret
= fwnode_property_read_string(fwnode
, "try-power-role", &cap_str
);
2240 ret
= typec_find_power_role(cap_str
);
2243 cap
->prefer_role
= ret
;
2249 EXPORT_SYMBOL_GPL(typec_get_fw_cap
);
2252 * typec_port_register_altmode - Register USB Type-C Port Alternate Mode
2253 * @port: USB Type-C Port that supports the alternate mode
2254 * @desc: Description of the alternate mode
2256 * This routine is used to register an alternate mode that @port is capable of
2259 * Returns handle to the alternate mode on success or ERR_PTR on failure.
2261 struct typec_altmode
*
2262 typec_port_register_altmode(struct typec_port
*port
,
2263 const struct typec_altmode_desc
*desc
)
2265 struct typec_altmode
*adev
;
2266 struct typec_mux
*mux
;
2267 struct typec_retimer
*retimer
;
2269 mux
= typec_mux_get(&port
->dev
);
2271 return ERR_CAST(mux
);
2273 retimer
= typec_retimer_get(&port
->dev
);
2274 if (IS_ERR(retimer
)) {
2276 return ERR_CAST(retimer
);
2279 adev
= typec_register_altmode(&port
->dev
, desc
);
2281 typec_retimer_put(retimer
);
2284 to_altmode(adev
)->mux
= mux
;
2285 to_altmode(adev
)->retimer
= retimer
;
2290 EXPORT_SYMBOL_GPL(typec_port_register_altmode
);
2292 void typec_port_register_altmodes(struct typec_port
*port
,
2293 const struct typec_altmode_ops
*ops
, void *drvdata
,
2294 struct typec_altmode
**altmodes
, size_t n
)
2296 struct fwnode_handle
*child
;
2297 struct typec_altmode_desc desc
;
2298 struct typec_altmode
*alt
;
2304 struct fwnode_handle
*altmodes_node
__free(fwnode_handle
) =
2305 device_get_named_child_node(&port
->dev
, "altmodes");
2308 return; /* No altmodes specified */
2310 fwnode_for_each_child_node(altmodes_node
, child
) {
2311 ret
= fwnode_property_read_u16(child
, "svid", &svid
);
2313 dev_err(&port
->dev
, "Error reading svid for altmode %s\n",
2314 fwnode_get_name(child
));
2318 ret
= fwnode_property_read_u32(child
, "vdo", &vdo
);
2320 dev_err(&port
->dev
, "Error reading vdo for altmode %s\n",
2321 fwnode_get_name(child
));
2326 dev_err(&port
->dev
, "Error not enough space for altmode %s\n",
2327 fwnode_get_name(child
));
2333 desc
.mode
= index
+ 1;
2334 alt
= typec_port_register_altmode(port
, &desc
);
2336 dev_err(&port
->dev
, "Error registering altmode %s\n",
2337 fwnode_get_name(child
));
2341 typec_altmode_set_ops(alt
, ops
);
2342 typec_altmode_set_drvdata(alt
, drvdata
);
2343 altmodes
[index
] = alt
;
2347 EXPORT_SYMBOL_GPL(typec_port_register_altmodes
);
2350 * typec_port_register_cable_ops - Register typec_cable_ops to port altmodes
2351 * @altmodes: USB Type-C Port's altmode vector
2352 * @max_altmodes: The maximum number of alt modes supported by the port
2353 * @ops: Cable alternate mode vector
2355 void typec_port_register_cable_ops(struct typec_altmode
**altmodes
, int max_altmodes
,
2356 const struct typec_cable_ops
*ops
)
2360 for (i
= 0; i
< max_altmodes
; i
++) {
2363 altmodes
[i
]->cable_ops
= ops
;
2366 EXPORT_SYMBOL_GPL(typec_port_register_cable_ops
);
2369 * typec_register_port - Register a USB Type-C Port
2370 * @parent: Parent device
2371 * @cap: Description of the port
2373 * Registers a device for USB Type-C Port described in @cap.
2375 * Returns handle to the port on success or ERR_PTR on failure.
2377 struct typec_port
*typec_register_port(struct device
*parent
,
2378 const struct typec_capability
*cap
)
2380 struct typec_port
*port
;
2384 port
= kzalloc(sizeof(*port
), GFP_KERNEL
);
2386 return ERR_PTR(-ENOMEM
);
2388 id
= ida_alloc(&typec_index_ida
, GFP_KERNEL
);
2394 switch (cap
->type
) {
2395 case TYPEC_PORT_SRC
:
2396 port
->pwr_role
= TYPEC_SOURCE
;
2397 port
->vconn_role
= TYPEC_SOURCE
;
2399 case TYPEC_PORT_SNK
:
2400 port
->pwr_role
= TYPEC_SINK
;
2401 port
->vconn_role
= TYPEC_SINK
;
2403 case TYPEC_PORT_DRP
:
2404 if (cap
->prefer_role
!= TYPEC_NO_PREFERRED_ROLE
)
2405 port
->pwr_role
= cap
->prefer_role
;
2407 port
->pwr_role
= TYPEC_SINK
;
2411 switch (cap
->data
) {
2412 case TYPEC_PORT_DFP
:
2413 port
->data_role
= TYPEC_HOST
;
2415 case TYPEC_PORT_UFP
:
2416 port
->data_role
= TYPEC_DEVICE
;
2418 case TYPEC_PORT_DRD
:
2419 if (cap
->prefer_role
== TYPEC_SOURCE
)
2420 port
->data_role
= TYPEC_HOST
;
2422 port
->data_role
= TYPEC_DEVICE
;
2426 ida_init(&port
->mode_ids
);
2427 mutex_init(&port
->port_type_lock
);
2430 port
->ops
= cap
->ops
;
2431 port
->port_type
= cap
->type
;
2432 port
->prefer_role
= cap
->prefer_role
;
2433 port
->con
.attach
= typec_partner_attach
;
2434 port
->con
.deattach
= typec_partner_deattach
;
2436 device_initialize(&port
->dev
);
2437 port
->dev
.class = &typec_class
;
2438 port
->dev
.parent
= parent
;
2439 port
->dev
.fwnode
= cap
->fwnode
;
2440 port
->dev
.type
= &typec_port_dev_type
;
2441 dev_set_name(&port
->dev
, "port%d", id
);
2442 dev_set_drvdata(&port
->dev
, cap
->driver_data
);
2444 port
->cap
= kmemdup(cap
, sizeof(*cap
), GFP_KERNEL
);
2446 put_device(&port
->dev
);
2447 return ERR_PTR(-ENOMEM
);
2450 port
->sw
= typec_switch_get(&port
->dev
);
2451 if (IS_ERR(port
->sw
)) {
2452 ret
= PTR_ERR(port
->sw
);
2453 put_device(&port
->dev
);
2454 return ERR_PTR(ret
);
2457 port
->mux
= typec_mux_get(&port
->dev
);
2458 if (IS_ERR(port
->mux
)) {
2459 ret
= PTR_ERR(port
->mux
);
2460 put_device(&port
->dev
);
2461 return ERR_PTR(ret
);
2464 port
->retimer
= typec_retimer_get(&port
->dev
);
2465 if (IS_ERR(port
->retimer
)) {
2466 ret
= PTR_ERR(port
->retimer
);
2467 put_device(&port
->dev
);
2468 return ERR_PTR(ret
);
2473 ret
= device_add(&port
->dev
);
2475 dev_err(parent
, "failed to register port (%d)\n", ret
);
2476 put_device(&port
->dev
);
2477 return ERR_PTR(ret
);
2480 ret
= usb_power_delivery_link_device(port
->pd
, &port
->dev
);
2482 dev_err(&port
->dev
, "failed to link pd\n");
2483 device_unregister(&port
->dev
);
2484 return ERR_PTR(ret
);
2487 ret
= typec_link_ports(port
);
2489 dev_warn(&port
->dev
, "failed to create symlinks (%d)\n", ret
);
2493 EXPORT_SYMBOL_GPL(typec_register_port
);
2496 * typec_unregister_port - Unregister a USB Type-C Port
2497 * @port: The port to be unregistered
2499 * Unregister device created with typec_register_port().
2501 void typec_unregister_port(struct typec_port
*port
)
2503 if (!IS_ERR_OR_NULL(port
)) {
2504 typec_unlink_ports(port
);
2505 typec_port_set_usb_power_delivery(port
, NULL
);
2506 device_unregister(&port
->dev
);
2509 EXPORT_SYMBOL_GPL(typec_unregister_port
);
2511 static int __init
typec_init(void)
2515 ret
= bus_register(&typec_bus
);
2519 ret
= class_register(&typec_mux_class
);
2521 goto err_unregister_bus
;
2523 ret
= class_register(&retimer_class
);
2525 goto err_unregister_mux_class
;
2527 ret
= class_register(&typec_class
);
2529 goto err_unregister_retimer_class
;
2531 ret
= usb_power_delivery_init();
2533 goto err_unregister_class
;
2537 err_unregister_class
:
2538 class_unregister(&typec_class
);
2540 err_unregister_retimer_class
:
2541 class_unregister(&retimer_class
);
2543 err_unregister_mux_class
:
2544 class_unregister(&typec_mux_class
);
2547 bus_unregister(&typec_bus
);
2551 subsys_initcall(typec_init
);
2553 static void __exit
typec_exit(void)
2555 usb_power_delivery_exit();
2556 class_unregister(&typec_class
);
2557 ida_destroy(&typec_index_ida
);
2558 bus_unregister(&typec_bus
);
2559 class_unregister(&typec_mux_class
);
2560 class_unregister(&retimer_class
);
2562 module_exit(typec_exit
);
2564 MODULE_AUTHOR("Heikki Krogerus <heikki.krogerus@linux.intel.com>");
2565 MODULE_LICENSE("GPL v2");
2566 MODULE_DESCRIPTION("USB Type-C Connector Class");