1 // SPDX-License-Identifier: GPL-2.0
3 * USB Power Delivery sysfs entries
5 * Copyright (C) 2022, Intel Corporation
9 #include <linux/slab.h>
10 #include <linux/usb/pd.h>
14 static DEFINE_IDA(pd_ida);
16 static struct class pd_class = {
17 .name = "usb_power_delivery",
21 #define to_pdo(o) container_of(o, struct pdo, dev)
29 static void pdo_release(struct device *dev)
34 /* -------------------------------------------------------------------------- */
38 dual_role_power_show(struct device *dev, struct device_attribute *attr, char *buf)
40 return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_DUAL_ROLE));
42 static DEVICE_ATTR_RO(dual_role_power);
45 usb_suspend_supported_show(struct device *dev, struct device_attribute *attr, char *buf)
47 return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_SUSPEND));
49 static DEVICE_ATTR_RO(usb_suspend_supported);
52 unconstrained_power_show(struct device *dev, struct device_attribute *attr, char *buf)
54 return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_EXTPOWER));
56 static DEVICE_ATTR_RO(unconstrained_power);
59 usb_communication_capable_show(struct device *dev, struct device_attribute *attr, char *buf)
61 return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_USB_COMM));
63 static DEVICE_ATTR_RO(usb_communication_capable);
66 dual_role_data_show(struct device *dev, struct device_attribute *attr, char *buf)
68 return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_DATA_SWAP));
70 static DEVICE_ATTR_RO(dual_role_data);
73 unchunked_extended_messages_supported_show(struct device *dev,
74 struct device_attribute *attr, char *buf)
76 return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & PDO_FIXED_UNCHUNK_EXT));
78 static DEVICE_ATTR_RO(unchunked_extended_messages_supported);
81 * REVISIT: Peak Current requires access also to the RDO.
83 peak_current_show(struct device *dev, struct device_attribute *attr, char *buf)
90 fast_role_swap_current_show(struct device *dev, struct device_attribute *attr, char *buf)
92 return sysfs_emit(buf, "%u\n", to_pdo(dev)->pdo >> PDO_FIXED_FRS_CURR_SHIFT) & 3;
94 static DEVICE_ATTR_RO(fast_role_swap_current);
96 static ssize_t voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
98 return sysfs_emit(buf, "%umV\n", pdo_fixed_voltage(to_pdo(dev)->pdo));
100 static DEVICE_ATTR_RO(voltage);
102 /* Shared with Variable supplies, both source and sink */
103 static ssize_t current_show(struct device *dev, struct device_attribute *attr, char *buf)
105 return sysfs_emit(buf, "%umA\n", pdo_max_current(to_pdo(dev)->pdo));
108 /* Shared with Variable type supplies */
109 static struct device_attribute maximum_current_attr = {
111 .name = "maximum_current",
114 .show = current_show,
117 static struct device_attribute operational_current_attr = {
119 .name = "operational_current",
122 .show = current_show,
125 static struct attribute *source_fixed_supply_attrs[] = {
126 &dev_attr_dual_role_power.attr,
127 &dev_attr_usb_suspend_supported.attr,
128 &dev_attr_unconstrained_power.attr,
129 &dev_attr_usb_communication_capable.attr,
130 &dev_attr_dual_role_data.attr,
131 &dev_attr_unchunked_extended_messages_supported.attr,
132 /*&dev_attr_peak_current.attr,*/
133 &dev_attr_voltage.attr,
134 &maximum_current_attr.attr,
138 static umode_t fixed_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n)
140 if (to_pdo(kobj_to_dev(kobj))->object_position &&
141 /*attr != &dev_attr_peak_current.attr &&*/
142 attr != &dev_attr_voltage.attr &&
143 attr != &maximum_current_attr.attr &&
144 attr != &operational_current_attr.attr)
150 static const struct attribute_group source_fixed_supply_group = {
151 .is_visible = fixed_attr_is_visible,
152 .attrs = source_fixed_supply_attrs,
154 __ATTRIBUTE_GROUPS(source_fixed_supply);
156 static struct device_type source_fixed_supply_type = {
158 .release = pdo_release,
159 .groups = source_fixed_supply_groups,
162 static struct attribute *sink_fixed_supply_attrs[] = {
163 &dev_attr_dual_role_power.attr,
164 &dev_attr_usb_suspend_supported.attr,
165 &dev_attr_unconstrained_power.attr,
166 &dev_attr_usb_communication_capable.attr,
167 &dev_attr_dual_role_data.attr,
168 &dev_attr_unchunked_extended_messages_supported.attr,
169 &dev_attr_fast_role_swap_current.attr,
170 &dev_attr_voltage.attr,
171 &operational_current_attr.attr,
175 static const struct attribute_group sink_fixed_supply_group = {
176 .is_visible = fixed_attr_is_visible,
177 .attrs = sink_fixed_supply_attrs,
179 __ATTRIBUTE_GROUPS(sink_fixed_supply);
181 static struct device_type sink_fixed_supply_type = {
183 .release = pdo_release,
184 .groups = sink_fixed_supply_groups,
187 /* -------------------------------------------------------------------------- */
188 /* Variable Supply */
191 maximum_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
193 return sysfs_emit(buf, "%umV\n", pdo_max_voltage(to_pdo(dev)->pdo));
195 static DEVICE_ATTR_RO(maximum_voltage);
198 minimum_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
200 return sysfs_emit(buf, "%umV\n", pdo_min_voltage(to_pdo(dev)->pdo));
202 static DEVICE_ATTR_RO(minimum_voltage);
204 static struct attribute *source_variable_supply_attrs[] = {
205 &dev_attr_maximum_voltage.attr,
206 &dev_attr_minimum_voltage.attr,
207 &maximum_current_attr.attr,
210 ATTRIBUTE_GROUPS(source_variable_supply);
212 static struct device_type source_variable_supply_type = {
214 .release = pdo_release,
215 .groups = source_variable_supply_groups,
218 static struct attribute *sink_variable_supply_attrs[] = {
219 &dev_attr_maximum_voltage.attr,
220 &dev_attr_minimum_voltage.attr,
221 &operational_current_attr.attr,
224 ATTRIBUTE_GROUPS(sink_variable_supply);
226 static struct device_type sink_variable_supply_type = {
228 .release = pdo_release,
229 .groups = sink_variable_supply_groups,
232 /* -------------------------------------------------------------------------- */
236 maximum_power_show(struct device *dev, struct device_attribute *attr, char *buf)
238 return sysfs_emit(buf, "%umW\n", pdo_max_power(to_pdo(dev)->pdo));
240 static DEVICE_ATTR_RO(maximum_power);
243 operational_power_show(struct device *dev, struct device_attribute *attr, char *buf)
245 return sysfs_emit(buf, "%umW\n", pdo_max_power(to_pdo(dev)->pdo));
247 static DEVICE_ATTR_RO(operational_power);
249 static struct attribute *source_battery_attrs[] = {
250 &dev_attr_maximum_voltage.attr,
251 &dev_attr_minimum_voltage.attr,
252 &dev_attr_maximum_power.attr,
255 ATTRIBUTE_GROUPS(source_battery);
257 static struct device_type source_battery_type = {
259 .release = pdo_release,
260 .groups = source_battery_groups,
263 static struct attribute *sink_battery_attrs[] = {
264 &dev_attr_maximum_voltage.attr,
265 &dev_attr_minimum_voltage.attr,
266 &dev_attr_operational_power.attr,
269 ATTRIBUTE_GROUPS(sink_battery);
271 static struct device_type sink_battery_type = {
273 .release = pdo_release,
274 .groups = sink_battery_groups,
277 /* -------------------------------------------------------------------------- */
278 /* Standard Power Range (SPR) Programmable Power Supply (PPS) */
281 pps_power_limited_show(struct device *dev, struct device_attribute *attr, char *buf)
283 return sysfs_emit(buf, "%u\n", !!(to_pdo(dev)->pdo & BIT(27)));
285 static DEVICE_ATTR_RO(pps_power_limited);
288 pps_max_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
290 return sysfs_emit(buf, "%umV\n", pdo_pps_apdo_max_voltage(to_pdo(dev)->pdo));
294 pps_min_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
296 return sysfs_emit(buf, "%umV\n", pdo_pps_apdo_min_voltage(to_pdo(dev)->pdo));
300 pps_max_current_show(struct device *dev, struct device_attribute *attr, char *buf)
302 return sysfs_emit(buf, "%umA\n", pdo_pps_apdo_max_current(to_pdo(dev)->pdo));
305 static struct device_attribute pps_max_voltage_attr = {
307 .name = "maximum_voltage",
310 .show = pps_max_voltage_show,
313 static struct device_attribute pps_min_voltage_attr = {
315 .name = "minimum_voltage",
318 .show = pps_min_voltage_show,
321 static struct device_attribute pps_max_current_attr = {
323 .name = "maximum_current",
326 .show = pps_max_current_show,
329 static struct attribute *source_pps_attrs[] = {
330 &dev_attr_pps_power_limited.attr,
331 &pps_max_voltage_attr.attr,
332 &pps_min_voltage_attr.attr,
333 &pps_max_current_attr.attr,
336 ATTRIBUTE_GROUPS(source_pps);
338 static struct device_type source_pps_type = {
340 .release = pdo_release,
341 .groups = source_pps_groups,
344 static struct attribute *sink_pps_attrs[] = {
345 &pps_max_voltage_attr.attr,
346 &pps_min_voltage_attr.attr,
347 &pps_max_current_attr.attr,
350 ATTRIBUTE_GROUPS(sink_pps);
352 static struct device_type sink_pps_type = {
354 .release = pdo_release,
355 .groups = sink_pps_groups,
358 /* -------------------------------------------------------------------------- */
360 static const char * const supply_name[] = {
361 [PDO_TYPE_FIXED] = "fixed_supply",
362 [PDO_TYPE_BATT] = "battery",
363 [PDO_TYPE_VAR] = "variable_supply",
366 static const char * const apdo_supply_name[] = {
367 [APDO_TYPE_PPS] = "programmable_supply",
370 static struct device_type *source_type[] = {
371 [PDO_TYPE_FIXED] = &source_fixed_supply_type,
372 [PDO_TYPE_BATT] = &source_battery_type,
373 [PDO_TYPE_VAR] = &source_variable_supply_type,
376 static struct device_type *source_apdo_type[] = {
377 [APDO_TYPE_PPS] = &source_pps_type,
380 static struct device_type *sink_type[] = {
381 [PDO_TYPE_FIXED] = &sink_fixed_supply_type,
382 [PDO_TYPE_BATT] = &sink_battery_type,
383 [PDO_TYPE_VAR] = &sink_variable_supply_type,
386 static struct device_type *sink_apdo_type[] = {
387 [APDO_TYPE_PPS] = &sink_pps_type,
390 /* REVISIT: Export when EPR_*_Capabilities need to be supported. */
391 static int add_pdo(struct usb_power_delivery_capabilities *cap, u32 pdo, int position)
393 struct device_type *type;
398 p = kzalloc(sizeof(*p), GFP_KERNEL);
403 p->object_position = position;
405 if (pdo_type(pdo) == PDO_TYPE_APDO) {
406 /* FIXME: Only PPS supported for now! Skipping others. */
407 if (pdo_apdo_type(pdo) > APDO_TYPE_PPS) {
408 dev_warn(&cap->dev, "Unknown APDO type. PDO 0x%08x\n", pdo);
413 if (is_source(cap->role))
414 type = source_apdo_type[pdo_apdo_type(pdo)];
416 type = sink_apdo_type[pdo_apdo_type(pdo)];
418 name = apdo_supply_name[pdo_apdo_type(pdo)];
420 if (is_source(cap->role))
421 type = source_type[pdo_type(pdo)];
423 type = sink_type[pdo_type(pdo)];
425 name = supply_name[pdo_type(pdo)];
428 p->dev.parent = &cap->dev;
430 dev_set_name(&p->dev, "%u:%s", position + 1, name);
432 ret = device_register(&p->dev);
441 static int remove_pdo(struct device *dev, void *data)
443 device_unregister(dev);
447 /* -------------------------------------------------------------------------- */
449 static const char * const cap_name[] = {
450 [TYPEC_SINK] = "sink-capabilities",
451 [TYPEC_SOURCE] = "source-capabilities",
454 static void pd_capabilities_release(struct device *dev)
456 kfree(to_usb_power_delivery_capabilities(dev));
459 static struct device_type pd_capabilities_type = {
460 .name = "capabilities",
461 .release = pd_capabilities_release,
465 * usb_power_delivery_register_capabilities - Register a set of capabilities.
466 * @pd: The USB PD instance that the capabilities belong to.
467 * @desc: Description of the Capablities Message.
469 * This function registers a Capabilities Message described in @desc. The
470 * capabilities will have their own sub-directory under @pd in sysfs.
472 * The function returns pointer to struct usb_power_delivery_capabilities, or
475 struct usb_power_delivery_capabilities *
476 usb_power_delivery_register_capabilities(struct usb_power_delivery *pd,
477 struct usb_power_delivery_capabilities_desc *desc)
479 struct usb_power_delivery_capabilities *cap;
483 cap = kzalloc(sizeof(*cap), GFP_KERNEL);
485 return ERR_PTR(-ENOMEM);
488 cap->role = desc->role;
490 cap->dev.parent = &pd->dev;
491 cap->dev.type = &pd_capabilities_type;
492 dev_set_name(&cap->dev, "%s", cap_name[cap->role]);
494 ret = device_register(&cap->dev);
496 put_device(&cap->dev);
500 for (i = 0; i < PDO_MAX_OBJECTS && desc->pdo[i]; i++) {
501 ret = add_pdo(cap, desc->pdo[i], i);
503 usb_power_delivery_unregister_capabilities(cap);
510 EXPORT_SYMBOL_GPL(usb_power_delivery_register_capabilities);
513 * usb_power_delivery_unregister_capabilities - Unregister a set of capabilities
514 * @cap: The capabilities
516 void usb_power_delivery_unregister_capabilities(struct usb_power_delivery_capabilities *cap)
521 device_for_each_child(&cap->dev, NULL, remove_pdo);
522 device_unregister(&cap->dev);
524 EXPORT_SYMBOL_GPL(usb_power_delivery_unregister_capabilities);
526 /* -------------------------------------------------------------------------- */
528 static ssize_t revision_show(struct device *dev, struct device_attribute *attr, char *buf)
530 struct usb_power_delivery *pd = to_usb_power_delivery(dev);
532 return sysfs_emit(buf, "%u.%u\n", (pd->revision >> 8) & 0xff, (pd->revision >> 4) & 0xf);
534 static DEVICE_ATTR_RO(revision);
536 static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf)
538 struct usb_power_delivery *pd = to_usb_power_delivery(dev);
540 return sysfs_emit(buf, "%u.%u\n", (pd->version >> 8) & 0xff, (pd->version >> 4) & 0xf);
542 static DEVICE_ATTR_RO(version);
544 static struct attribute *pd_attrs[] = {
545 &dev_attr_revision.attr,
546 &dev_attr_version.attr,
550 static umode_t pd_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n)
552 struct usb_power_delivery *pd = to_usb_power_delivery(kobj_to_dev(kobj));
554 if (attr == &dev_attr_version.attr && !pd->version)
560 static const struct attribute_group pd_group = {
561 .is_visible = pd_attr_is_visible,
564 __ATTRIBUTE_GROUPS(pd);
566 static void pd_release(struct device *dev)
568 struct usb_power_delivery *pd = to_usb_power_delivery(dev);
570 ida_simple_remove(&pd_ida, pd->id);
574 static struct device_type pd_type = {
575 .name = "usb_power_delivery",
576 .release = pd_release,
580 struct usb_power_delivery *usb_power_delivery_find(const char *name)
584 dev = class_find_device_by_name(&pd_class, name);
586 return dev ? to_usb_power_delivery(dev) : NULL;
590 * usb_power_delivery_register - Register USB Power Delivery Support.
591 * @parent: Parent device.
592 * @desc: Description of the USB PD contract.
594 * This routine can be used to register USB Power Delivery capabilities that a
595 * device or devices can support. These capabilities represent all the
596 * capabilities that can be negotiated with a partner, so not only the Power
597 * Capabilities that are negotiated using the USB PD Capabilities Message.
599 * The USB Power Delivery Support object that this routine generates can be used
600 * as the parent object for all the actual USB Power Delivery Messages and
601 * objects that can be negotiated with the partner.
603 * Returns handle to struct usb_power_delivery or ERR_PTR.
605 struct usb_power_delivery *
606 usb_power_delivery_register(struct device *parent, struct usb_power_delivery_desc *desc)
608 struct usb_power_delivery *pd;
611 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
613 return ERR_PTR(-ENOMEM);
615 ret = ida_simple_get(&pd_ida, 0, 0, GFP_KERNEL);
622 pd->revision = desc->revision;
623 pd->version = desc->version;
625 pd->dev.parent = parent;
626 pd->dev.type = &pd_type;
627 pd->dev.class = &pd_class;
628 dev_set_name(&pd->dev, "pd%d", pd->id);
630 ret = device_register(&pd->dev);
632 put_device(&pd->dev);
638 EXPORT_SYMBOL_GPL(usb_power_delivery_register);
641 * usb_power_delivery_unregister - Unregister USB Power Delivery Support.
642 * @pd: The USB PD contract.
644 void usb_power_delivery_unregister(struct usb_power_delivery *pd)
646 if (IS_ERR_OR_NULL(pd))
649 device_unregister(&pd->dev);
651 EXPORT_SYMBOL_GPL(usb_power_delivery_unregister);
654 * usb_power_delivery_link_device - Link device to its USB PD object.
655 * @pd: The USB PD instance.
658 * This function can be used to create a symlink named "usb_power_delivery" for
659 * @dev that points to @pd.
661 int usb_power_delivery_link_device(struct usb_power_delivery *pd, struct device *dev)
665 if (IS_ERR_OR_NULL(pd) || !dev)
668 ret = sysfs_create_link(&dev->kobj, &pd->dev.kobj, "usb_power_delivery");
672 get_device(&pd->dev);
677 EXPORT_SYMBOL_GPL(usb_power_delivery_link_device);
680 * usb_power_delivery_unlink_device - Unlink device from its USB PD object.
681 * @pd: The USB PD instance.
684 * Remove the symlink that was previously created with pd_link_device().
686 void usb_power_delivery_unlink_device(struct usb_power_delivery *pd, struct device *dev)
688 if (IS_ERR_OR_NULL(pd) || !dev)
691 sysfs_remove_link(&dev->kobj, "usb_power_delivery");
692 put_device(&pd->dev);
695 EXPORT_SYMBOL_GPL(usb_power_delivery_unlink_device);
697 /* -------------------------------------------------------------------------- */
699 int __init usb_power_delivery_init(void)
701 return class_register(&pd_class);
704 void __exit usb_power_delivery_exit(void)
706 ida_destroy(&pd_ida);
707 class_unregister(&pd_class);