Skip to content

Commit cf45004

Browse files
Adam Thomsongregkh
authored andcommitted
power: supply: Add 'usb_type' property and supporting code
This commit adds the 'usb_type' property to represent USB supplies which can report a number of different types based on a connection event. Examples of this already exist in drivers whereby the existing 'type' property is updated, based on an event, to represent what was connected (e.g. USB, USB_DCP, USB_ACA, ...). Current implementations however don't show all supported connectable types, so this knowledge has to be exlicitly known for each driver that supports this. The 'usb_type' property is intended to fill this void and show users all possible USB types supported by a driver. The property, when read, shows all available types for the driver, and the one currently chosen is highlighted/bracketed. It is expected that the 'type' property would then just show the top-level type 'USB', and this would be static. Currently the 'usb_type' enum contains all of the USB variant types that exist for the 'type' enum at this time, and in addition has SDP and PPS types. The mirroring is intentional so as to not impact existing usage of the 'type' property. Signed-off-by: Adam Thomson <[email protected]> Reviewed-by: Heikki Krogerus <[email protected]> Reviewed-by: Sebastian Reichel <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 1ac3eef commit cf45004

File tree

4 files changed

+80
-1
lines changed

4 files changed

+80
-1
lines changed

Documentation/ABI/testing/sysfs-class-power

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,18 @@ Description:
409409
Access: Read
410410
Valid values: Represented in 1/10 Degrees Celsius
411411

412+
What: /sys/class/power_supply/<supply_name>/usb_type
413+
Date: March 2018
414+
415+
Description:
416+
Reports what type of USB connection is currently active for
417+
the supply, for example it can show if USB-PD capable source
418+
is attached.
419+
420+
Access: Read-Only
421+
Valid values: "Unknown", "SDP", "DCP", "CDP", "ACA", "C", "PD",
422+
"PD_DRP", "PD_PPS", "BrickID"
423+
412424
What: /sys/class/power_supply/<supply_name>/voltage_max
413425
Date: January 2008
414426

drivers/power/supply/power_supply_core.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ __power_supply_register(struct device *parent,
843843
{
844844
struct device *dev;
845845
struct power_supply *psy;
846-
int rc;
846+
int i, rc;
847847

848848
if (!parent)
849849
pr_warn("%s: Expected proper parent device for '%s'\n",
@@ -852,6 +852,12 @@ __power_supply_register(struct device *parent,
852852
if (!desc || !desc->name || !desc->properties || !desc->num_properties)
853853
return ERR_PTR(-EINVAL);
854854

855+
for (i = 0; i < desc->num_properties; ++i) {
856+
if ((desc->properties[i] == POWER_SUPPLY_PROP_USB_TYPE) &&
857+
(!desc->usb_types || !desc->num_usb_types))
858+
return ERR_PTR(-EINVAL);
859+
}
860+
855861
psy = kzalloc(sizeof(*psy), GFP_KERNEL);
856862
if (!psy)
857863
return ERR_PTR(-ENOMEM);

drivers/power/supply/power_supply_sysfs.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ static const char * const power_supply_type_text[] = {
4646
"USB_PD", "USB_PD_DRP", "BrickID"
4747
};
4848

49+
static const char * const power_supply_usb_type_text[] = {
50+
"Unknown", "SDP", "DCP", "CDP", "ACA", "C",
51+
"PD", "PD_DRP", "PD_PPS", "BrickID"
52+
};
53+
4954
static const char * const power_supply_status_text[] = {
5055
"Unknown", "Charging", "Discharging", "Not charging", "Full"
5156
};
@@ -73,6 +78,41 @@ static const char * const power_supply_scope_text[] = {
7378
"Unknown", "System", "Device"
7479
};
7580

81+
static ssize_t power_supply_show_usb_type(struct device *dev,
82+
enum power_supply_usb_type *usb_types,
83+
ssize_t num_usb_types,
84+
union power_supply_propval *value,
85+
char *buf)
86+
{
87+
enum power_supply_usb_type usb_type;
88+
ssize_t count = 0;
89+
bool match = false;
90+
int i;
91+
92+
for (i = 0; i < num_usb_types; ++i) {
93+
usb_type = usb_types[i];
94+
95+
if (value->intval == usb_type) {
96+
count += sprintf(buf + count, "[%s] ",
97+
power_supply_usb_type_text[usb_type]);
98+
match = true;
99+
} else {
100+
count += sprintf(buf + count, "%s ",
101+
power_supply_usb_type_text[usb_type]);
102+
}
103+
}
104+
105+
if (!match) {
106+
dev_warn(dev, "driver reporting unsupported connected type\n");
107+
return -EINVAL;
108+
}
109+
110+
if (count)
111+
buf[count - 1] = '\n';
112+
113+
return count;
114+
}
115+
76116
static ssize_t power_supply_show_property(struct device *dev,
77117
struct device_attribute *attr,
78118
char *buf) {
@@ -115,6 +155,10 @@ static ssize_t power_supply_show_property(struct device *dev,
115155
else if (off == POWER_SUPPLY_PROP_TYPE)
116156
return sprintf(buf, "%s\n",
117157
power_supply_type_text[value.intval]);
158+
else if (off == POWER_SUPPLY_PROP_USB_TYPE)
159+
return power_supply_show_usb_type(dev, psy->desc->usb_types,
160+
psy->desc->num_usb_types,
161+
&value, buf);
118162
else if (off == POWER_SUPPLY_PROP_SCOPE)
119163
return sprintf(buf, "%s\n",
120164
power_supply_scope_text[value.intval]);
@@ -241,6 +285,7 @@ static struct device_attribute power_supply_attrs[] = {
241285
POWER_SUPPLY_ATTR(time_to_full_now),
242286
POWER_SUPPLY_ATTR(time_to_full_avg),
243287
POWER_SUPPLY_ATTR(type),
288+
POWER_SUPPLY_ATTR(usb_type),
244289
POWER_SUPPLY_ATTR(scope),
245290
POWER_SUPPLY_ATTR(precharge_current),
246291
POWER_SUPPLY_ATTR(charge_term_current),

include/linux/power_supply.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ enum power_supply_property {
145145
POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
146146
POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
147147
POWER_SUPPLY_PROP_TYPE, /* use power_supply.type instead */
148+
POWER_SUPPLY_PROP_USB_TYPE,
148149
POWER_SUPPLY_PROP_SCOPE,
149150
POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
150151
POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
@@ -170,6 +171,19 @@ enum power_supply_type {
170171
POWER_SUPPLY_TYPE_APPLE_BRICK_ID, /* Apple Charging Method */
171172
};
172173

174+
enum power_supply_usb_type {
175+
POWER_SUPPLY_USB_TYPE_UNKNOWN = 0,
176+
POWER_SUPPLY_USB_TYPE_SDP, /* Standard Downstream Port */
177+
POWER_SUPPLY_USB_TYPE_DCP, /* Dedicated Charging Port */
178+
POWER_SUPPLY_USB_TYPE_CDP, /* Charging Downstream Port */
179+
POWER_SUPPLY_USB_TYPE_ACA, /* Accessory Charger Adapters */
180+
POWER_SUPPLY_USB_TYPE_C, /* Type C Port */
181+
POWER_SUPPLY_USB_TYPE_PD, /* Power Delivery Port */
182+
POWER_SUPPLY_USB_TYPE_PD_DRP, /* PD Dual Role Port */
183+
POWER_SUPPLY_USB_TYPE_PD_PPS, /* PD Programmable Power Supply */
184+
POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID, /* Apple Charging Method */
185+
};
186+
173187
enum power_supply_notifier_events {
174188
PSY_EVENT_PROP_CHANGED,
175189
};
@@ -196,6 +210,8 @@ struct power_supply_config {
196210
struct power_supply_desc {
197211
const char *name;
198212
enum power_supply_type type;
213+
enum power_supply_usb_type *usb_types;
214+
size_t num_usb_types;
199215
enum power_supply_property *properties;
200216
size_t num_properties;
201217

0 commit comments

Comments
 (0)