diff options
Diffstat (limited to 'drivers/power/supply/power_supply_sysfs.c')
-rw-r--r-- | drivers/power/supply/power_supply_sysfs.c | 123 |
1 files changed, 90 insertions, 33 deletions
diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c index 5204f115970f..6170ed8b6854 100644 --- a/drivers/power/supply/power_supply_sysfs.c +++ b/drivers/power/supply/power_supply_sysfs.c @@ -46,6 +46,11 @@ static const char * const power_supply_type_text[] = { "USB_PD", "USB_PD_DRP", "BrickID" }; +static const char * const power_supply_usb_type_text[] = { + "Unknown", "SDP", "DCP", "CDP", "ACA", "C", + "PD", "PD_DRP", "PD_PPS", "BrickID" +}; + static const char * const power_supply_status_text[] = { "Unknown", "Charging", "Discharging", "Not charging", "Full" }; @@ -73,18 +78,53 @@ static const char * const power_supply_scope_text[] = { "Unknown", "System", "Device" }; +static ssize_t power_supply_show_usb_type(struct device *dev, + enum power_supply_usb_type *usb_types, + ssize_t num_usb_types, + union power_supply_propval *value, + char *buf) +{ + enum power_supply_usb_type usb_type; + ssize_t count = 0; + bool match = false; + int i; + + for (i = 0; i < num_usb_types; ++i) { + usb_type = usb_types[i]; + + if (value->intval == usb_type) { + count += sprintf(buf + count, "[%s] ", + power_supply_usb_type_text[usb_type]); + match = true; + } else { + count += sprintf(buf + count, "%s ", + power_supply_usb_type_text[usb_type]); + } + } + + if (!match) { + dev_warn(dev, "driver reporting unsupported connected type\n"); + return -EINVAL; + } + + if (count) + buf[count - 1] = '\n'; + + return count; +} + static ssize_t power_supply_show_property(struct device *dev, struct device_attribute *attr, char *buf) { - ssize_t ret = 0; + ssize_t ret; struct power_supply *psy = dev_get_drvdata(dev); - const ptrdiff_t off = attr - power_supply_attrs; + enum power_supply_property psp = attr - power_supply_attrs; union power_supply_propval value; - if (off == POWER_SUPPLY_PROP_TYPE) { + if (psp == POWER_SUPPLY_PROP_TYPE) { value.intval = psy->desc->type; } else { - ret = power_supply_get_property(psy, off, &value); + ret = power_supply_get_property(psy, psp, &value); if (ret < 0) { if (ret == -ENODATA) @@ -97,31 +137,48 @@ static ssize_t power_supply_show_property(struct device *dev, } } - if (off == POWER_SUPPLY_PROP_STATUS) - return sprintf(buf, "%s\n", - power_supply_status_text[value.intval]); - else if (off == POWER_SUPPLY_PROP_CHARGE_TYPE) - return sprintf(buf, "%s\n", - power_supply_charge_type_text[value.intval]); - else if (off == POWER_SUPPLY_PROP_HEALTH) - return sprintf(buf, "%s\n", - power_supply_health_text[value.intval]); - else if (off == POWER_SUPPLY_PROP_TECHNOLOGY) - return sprintf(buf, "%s\n", - power_supply_technology_text[value.intval]); - else if (off == POWER_SUPPLY_PROP_CAPACITY_LEVEL) - return sprintf(buf, "%s\n", - power_supply_capacity_level_text[value.intval]); - else if (off == POWER_SUPPLY_PROP_TYPE) - return sprintf(buf, "%s\n", - power_supply_type_text[value.intval]); - else if (off == POWER_SUPPLY_PROP_SCOPE) - return sprintf(buf, "%s\n", - power_supply_scope_text[value.intval]); - else if (off >= POWER_SUPPLY_PROP_MODEL_NAME) - return sprintf(buf, "%s\n", value.strval); - - return sprintf(buf, "%d\n", value.intval); + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + ret = sprintf(buf, "%s\n", + power_supply_status_text[value.intval]); + break; + case POWER_SUPPLY_PROP_CHARGE_TYPE: + ret = sprintf(buf, "%s\n", + power_supply_charge_type_text[value.intval]); + break; + case POWER_SUPPLY_PROP_HEALTH: + ret = sprintf(buf, "%s\n", + power_supply_health_text[value.intval]); + break; + case POWER_SUPPLY_PROP_TECHNOLOGY: + ret = sprintf(buf, "%s\n", + power_supply_technology_text[value.intval]); + break; + case POWER_SUPPLY_PROP_CAPACITY_LEVEL: + ret = sprintf(buf, "%s\n", + power_supply_capacity_level_text[value.intval]); + break; + case POWER_SUPPLY_PROP_TYPE: + ret = sprintf(buf, "%s\n", + power_supply_type_text[value.intval]); + break; + case POWER_SUPPLY_PROP_USB_TYPE: + ret = power_supply_show_usb_type(dev, psy->desc->usb_types, + psy->desc->num_usb_types, + &value, buf); + break; + case POWER_SUPPLY_PROP_SCOPE: + ret = sprintf(buf, "%s\n", + power_supply_scope_text[value.intval]); + break; + case POWER_SUPPLY_PROP_MODEL_NAME ... POWER_SUPPLY_PROP_SERIAL_NUMBER: + ret = sprintf(buf, "%s\n", value.strval); + break; + default: + ret = sprintf(buf, "%d\n", value.intval); + } + + return ret; } static ssize_t power_supply_store_property(struct device *dev, @@ -129,11 +186,10 @@ static ssize_t power_supply_store_property(struct device *dev, const char *buf, size_t count) { ssize_t ret; struct power_supply *psy = dev_get_drvdata(dev); - const ptrdiff_t off = attr - power_supply_attrs; + enum power_supply_property psp = attr - power_supply_attrs; union power_supply_propval value; - /* maybe it is a enum property? */ - switch (off) { + switch (psp) { case POWER_SUPPLY_PROP_STATUS: ret = sysfs_match_string(power_supply_status_text, buf); break; @@ -172,7 +228,7 @@ static ssize_t power_supply_store_property(struct device *dev, value.intval = ret; - ret = power_supply_set_property(psy, off, &value); + ret = power_supply_set_property(psy, psp, &value); if (ret < 0) return ret; @@ -241,6 +297,7 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(time_to_full_now), POWER_SUPPLY_ATTR(time_to_full_avg), POWER_SUPPLY_ATTR(type), + POWER_SUPPLY_ATTR(usb_type), POWER_SUPPLY_ATTR(scope), POWER_SUPPLY_ATTR(precharge_current), POWER_SUPPLY_ATTR(charge_term_current), |