diff options
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/avs/rockchip-io-domain.c | 68 | ||||
-rw-r--r-- | drivers/power/supply/power_supply_core.c | 15 | ||||
-rw-r--r-- | drivers/power/supply/power_supply_sysfs.c | 45 |
3 files changed, 126 insertions, 2 deletions
diff --git a/drivers/power/avs/rockchip-io-domain.c b/drivers/power/avs/rockchip-io-domain.c index ed2b109ae8fc..d6a5e6bf5f12 100644 --- a/drivers/power/avs/rockchip-io-domain.c +++ b/drivers/power/avs/rockchip-io-domain.c @@ -39,6 +39,10 @@ #define MAX_VOLTAGE_1_8 1980000 #define MAX_VOLTAGE_3_3 3600000 +#define PX30_IO_VSEL 0x180 +#define PX30_IO_VSEL_VCCIO6_SRC BIT(0) +#define PX30_IO_VSEL_VCCIO6_SUPPLY_NUM 1 + #define RK3288_SOC_CON2 0x24c #define RK3288_SOC_CON2_FLASH0 BIT(7) #define RK3288_SOC_FLASH_SUPPLY_NUM 2 @@ -151,6 +155,25 @@ static int rockchip_iodomain_notify(struct notifier_block *nb, return NOTIFY_OK; } +static void px30_iodomain_init(struct rockchip_iodomain *iod) +{ + int ret; + u32 val; + + /* if no VCCIO0 supply we should leave things alone */ + if (!iod->supplies[PX30_IO_VSEL_VCCIO6_SUPPLY_NUM].reg) + return; + + /* + * set vccio0 iodomain to also use this framework + * instead of a special gpio. + */ + val = PX30_IO_VSEL_VCCIO6_SRC | (PX30_IO_VSEL_VCCIO6_SRC << 16); + ret = regmap_write(iod->grf, PX30_IO_VSEL, val); + if (ret < 0) + dev_warn(iod->dev, "couldn't update vccio0 ctrl\n"); +} + static void rk3288_iodomain_init(struct rockchip_iodomain *iod) { int ret; @@ -227,6 +250,43 @@ static void rk3399_pmu_iodomain_init(struct rockchip_iodomain *iod) dev_warn(iod->dev, "couldn't update pmu io iodomain ctrl\n"); } +static const struct rockchip_iodomain_soc_data soc_data_px30 = { + .grf_offset = 0x180, + .supply_names = { + NULL, + "vccio6", + "vccio1", + "vccio2", + "vccio3", + "vccio4", + "vccio5", + "vccio-oscgpi", + }, + .init = px30_iodomain_init, +}; + +static const struct rockchip_iodomain_soc_data soc_data_px30_pmu = { + .grf_offset = 0x100, + .supply_names = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "pmuio1", + "pmuio2", + }, +}; + /* * On the rk3188 the io-domains are handled by a shared register with the * lower 8 bits being still being continuing drive-strength settings. @@ -381,6 +441,14 @@ static const struct rockchip_iodomain_soc_data soc_data_rv1108_pmu = { static const struct of_device_id rockchip_iodomain_match[] = { { + .compatible = "rockchip,px30-io-voltage-domain", + .data = (void *)&soc_data_px30 + }, + { + .compatible = "rockchip,px30-pmu-io-voltage-domain", + .data = (void *)&soc_data_px30_pmu + }, + { .compatible = "rockchip,rk3188-io-voltage-domain", .data = &soc_data_rk3188 }, diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c index feac7b066e6c..f57ab0a27301 100644 --- a/drivers/power/supply/power_supply_core.c +++ b/drivers/power/supply/power_supply_core.c @@ -19,6 +19,7 @@ #include <linux/err.h> #include <linux/of.h> #include <linux/power_supply.h> +#include <linux/property.h> #include <linux/thermal.h> #include "power_supply.h" @@ -843,12 +844,21 @@ __power_supply_register(struct device *parent, { struct device *dev; struct power_supply *psy; - int rc; + int i, rc; if (!parent) pr_warn("%s: Expected proper parent device for '%s'\n", __func__, desc->name); + if (!desc || !desc->name || !desc->properties || !desc->num_properties) + return ERR_PTR(-EINVAL); + + for (i = 0; i < desc->num_properties; ++i) { + if ((desc->properties[i] == POWER_SUPPLY_PROP_USB_TYPE) && + (!desc->usb_types || !desc->num_usb_types)) + return ERR_PTR(-EINVAL); + } + psy = kzalloc(sizeof(*psy), GFP_KERNEL); if (!psy) return ERR_PTR(-ENOMEM); @@ -865,7 +875,8 @@ __power_supply_register(struct device *parent, psy->desc = desc; if (cfg) { psy->drv_data = cfg->drv_data; - psy->of_node = cfg->of_node; + psy->of_node = + cfg->fwnode ? to_of_node(cfg->fwnode) : cfg->of_node; psy->supplied_to = cfg->supplied_to; psy->num_supplicants = cfg->num_supplicants; } diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c index 5204f115970f..1350068c401a 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,6 +78,41 @@ 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) { @@ -115,6 +155,10 @@ static ssize_t power_supply_show_property(struct device *dev, else if (off == POWER_SUPPLY_PROP_TYPE) return sprintf(buf, "%s\n", power_supply_type_text[value.intval]); + else if (off == POWER_SUPPLY_PROP_USB_TYPE) + return power_supply_show_usb_type(dev, psy->desc->usb_types, + psy->desc->num_usb_types, + &value, buf); else if (off == POWER_SUPPLY_PROP_SCOPE) return sprintf(buf, "%s\n", power_supply_scope_text[value.intval]); @@ -241,6 +285,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), |