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