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