projects/linux·blob master · refs

2965 lines · 74.7 KiB

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