From patchwork Wed May 29 07:11:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Smirnov X-Patchwork-Id: 10966185 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ADAD76C5 for ; Wed, 29 May 2019 07:11:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 994CA28714 for ; Wed, 29 May 2019 07:11:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8D51E28795; Wed, 29 May 2019 07:11:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A73BF28714 for ; Wed, 29 May 2019 07:11:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726581AbfE2HLb (ORCPT ); Wed, 29 May 2019 03:11:31 -0400 Received: from mail-pl1-f193.google.com ([209.85.214.193]:35570 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725882AbfE2HL3 (ORCPT ); Wed, 29 May 2019 03:11:29 -0400 Received: by mail-pl1-f193.google.com with SMTP id p1so665212plo.2; Wed, 29 May 2019 00:11:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ray55oNe1T3sHn83tx/zmaoCA1rDD8hjIrwtAFH2eUs=; b=JSs8T2oGvevGGRMYbzTrFJINZTIB2hsq8myEVTD1clVZi0GEJfAeaVDeAV05qJLUWh 1dpvW8e34CWHH0rok1lDbOgEts4UCWRA1oJyshC80+OU6n0WiBsjk+q7q4SbkvbMIHsF RL0Q/2Hcb6nitrrAKVEYDt334I3hK2FTk+vRYeYCl+IvQ9v5NqpQW1Lt5F+cySf0bGDf QFPTemHr7L+3tTJpI4bFS5sYBvVlBShjaFx7LiDZQ1WU+1+0GQDhg1qcQ0IUWv/i0DUC OZHWgaTcNhTT24vsKDNl/MFoNxirqoF9s9KjGVwwu9nDgHQ9Mikhx0oXUhjbQaCgViI5 /PqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ray55oNe1T3sHn83tx/zmaoCA1rDD8hjIrwtAFH2eUs=; b=p3+if4pR3xGLVvPS6n4jQvpP7w3RUVUXNvxvBqcNMMsJCob8whOM4eYcSiik6CHgwt J0DNt2fM35BcjHI3Lv+JlAbMAC9i7GE5EZcO/MkSUcgloVXm8AAmECaf+FZA9Nn/7T0j XR5pYhiEHcutCFZIvcgT5Cl+ZEKGMnaWwQSm4MFTufPjTGLrct0u16wDXCtsE4wsOutH 5Cn9/yA0TUlqWFhns9I5xYYl0R+D0JZzFa6w/WqKV1U2lHmFVONIE2FLuUp7prb2I6Ai SqXchjJgEW1m2r398TR79SwTohzLRlePiDXHAfJ9XCwNeHAUVpoOD/OumTUM29bQ/LOF QiXQ== X-Gm-Message-State: APjAAAVyp6f7dAmLkSz7Qqr8pmp0k4qub041UGr/p1EW+2KG+cBUCbpo Xj0kq8dZmmgHR1toJw14nMp1FyMidCo= X-Google-Smtp-Source: APXvYqxaG5kJGFyPIGI/Erunt+tNaXmwJ1Nfwj47wz9Hvo5cAlxqlHwv3LuMSjOc6vYUgKeCaN1UGg== X-Received: by 2002:a17:902:b195:: with SMTP id s21mr37904851plr.16.1559113888635; Wed, 29 May 2019 00:11:28 -0700 (PDT) Received: from localhost.lan (c-24-22-235-96.hsd1.wa.comcast.net. [24.22.235.96]) by smtp.gmail.com with ESMTPSA id u20sm18083307pfm.145.2019.05.29.00.11.27 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 29 May 2019 00:11:27 -0700 (PDT) From: Andrey Smirnov To: linux-pm@vger.kernel.org Cc: Andrey Smirnov , Chris Healy , Lucas Stach , Fabio Estevam , Guenter Roeck , Sebastian Reichel , linux-kernel@vger.kernel.org Subject: [PATCH 1/2] power: supply: Add HWMON compatibility layer Date: Wed, 29 May 2019 00:11:11 -0700 Message-Id: <20190529071112.16849-2-andrew.smirnov@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190529071112.16849-1-andrew.smirnov@gmail.com> References: <20190529071112.16849-1-andrew.smirnov@gmail.com> MIME-Version: 1.0 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add code implementing HWMON adapter/compatibility layer to allow expositing various sensors present on power supply devices via HWMON subsystem. This is done in order to allow userspace to use single ABI/library(libsensors) to access/manipulate all of the sensors of the system. Signed-off-by: Andrey Smirnov Cc: Chris Healy Cc: Lucas Stach Cc: Fabio Estevam Cc: Guenter Roeck Cc: Sebastian Reichel Cc: linux-kernel@vger.kernel.org Cc: linux-pm@vger.kernel.org --- drivers/power/supply/Kconfig | 14 + drivers/power/supply/Makefile | 1 + drivers/power/supply/power_supply_hwmon.c | 329 ++++++++++++++++++++++ include/linux/power_supply.h | 11 + 4 files changed, 355 insertions(+) create mode 100644 drivers/power/supply/power_supply_hwmon.c diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index 26dacdab03cc..1f2252cb95fd 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -14,6 +14,20 @@ config POWER_SUPPLY_DEBUG Say Y here to enable debugging messages for power supply class and drivers. +config POWER_SUPPLY_HWMON + bool + prompt "Expose power supply sensors as hwmon device" + depends on HWMON=y || HWMON=POWER_SUPPLY + default y + help + This options enables API that allows sensors found on a + power supply device (current, voltage, temperature) to be + exposed as a hwmon device. + + Say 'Y' here if you want power supplies to + have hwmon sysfs interface too. + + config PDA_POWER tristate "Generic PDA/phone power driver" depends on !S390 diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile index f208273f9686..c47e88ba16b9 100644 --- a/drivers/power/supply/Makefile +++ b/drivers/power/supply/Makefile @@ -6,6 +6,7 @@ power_supply-$(CONFIG_SYSFS) += power_supply_sysfs.o power_supply-$(CONFIG_LEDS_TRIGGERS) += power_supply_leds.o obj-$(CONFIG_POWER_SUPPLY) += power_supply.o +obj-$(CONFIG_POWER_SUPPLY_HWMON) += power_supply_hwmon.o obj-$(CONFIG_GENERIC_ADC_BATTERY) += generic-adc-battery.o obj-$(CONFIG_PDA_POWER) += pda_power.o diff --git a/drivers/power/supply/power_supply_hwmon.c b/drivers/power/supply/power_supply_hwmon.c new file mode 100644 index 000000000000..dca7f79fae6e --- /dev/null +++ b/drivers/power/supply/power_supply_hwmon.c @@ -0,0 +1,329 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * power_supply_hwmon.c - power supply hwmon support. + */ + +#include +#include +#include +#include + +struct power_supply_hwmon { + struct power_supply *psy; + unsigned long *props; +}; + +static int power_supply_hwmon_in_to_property(u32 attr) +{ + switch (attr) { + case hwmon_in_average: + return POWER_SUPPLY_PROP_VOLTAGE_AVG; + case hwmon_in_min: + return POWER_SUPPLY_PROP_VOLTAGE_MIN; + case hwmon_in_max: + return POWER_SUPPLY_PROP_VOLTAGE_MAX; + case hwmon_in_input: + return POWER_SUPPLY_PROP_VOLTAGE_NOW; + default: + break; + } + + return -EINVAL; +} + +static int power_supply_hwmon_curr_to_property(u32 attr) +{ + switch (attr) { + case hwmon_curr_average: + return POWER_SUPPLY_PROP_CURRENT_AVG; + case hwmon_curr_max: + return POWER_SUPPLY_PROP_CURRENT_MAX; + case hwmon_curr_input: + return POWER_SUPPLY_PROP_CURRENT_NOW; + default: + break; + } + + return -EINVAL; +} + +static int power_supply_hwmon_temp_to_property(u32 attr, int channel) +{ + if (channel) { + switch (attr) { + case hwmon_temp_input: + return POWER_SUPPLY_PROP_TEMP_AMBIENT; + case hwmon_temp_min_alarm: + return POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN; + case hwmon_temp_max_alarm: + return POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX; + default: + break; + } + } else { + switch (attr) { + case hwmon_temp_input: + return POWER_SUPPLY_PROP_TEMP; + case hwmon_temp_max: + return POWER_SUPPLY_PROP_TEMP_MAX; + case hwmon_temp_min: + return POWER_SUPPLY_PROP_TEMP_MIN; + case hwmon_temp_min_alarm: + return POWER_SUPPLY_PROP_TEMP_ALERT_MIN; + case hwmon_temp_max_alarm: + return POWER_SUPPLY_PROP_TEMP_ALERT_MAX; + default: + break; + } + } + + return -EINVAL; +} + +static int +power_supply_hwmon_to_property(enum hwmon_sensor_types type, + u32 attr, int channel) +{ + switch (type) { + case hwmon_in: + return power_supply_hwmon_in_to_property(attr); + case hwmon_curr: + return power_supply_hwmon_curr_to_property(attr); + case hwmon_temp: + return power_supply_hwmon_temp_to_property(attr, channel); + default: + break; + } + + return -EINVAL; +} + +static bool power_supply_hwmon_is_a_label(enum hwmon_sensor_types type, + u32 attr) +{ + return type == hwmon_temp && attr == hwmon_temp_label; +} + +static umode_t power_supply_hwmon_is_visible(const void *data, + enum hwmon_sensor_types type, + u32 attr, int channel) +{ + const struct power_supply_hwmon *psyhw = data; + int prop, is_writable; + + if (power_supply_hwmon_is_a_label(type, attr)) + return 0444; + + prop = power_supply_hwmon_to_property(type, attr, channel); + if (prop < 0 || !test_bit(prop, psyhw->props)) + return 0; + + is_writable = power_supply_property_is_writeable(psyhw->psy, prop); + + return (is_writable <= 0) ? 0444 : 0644; +} + +static int power_supply_hwmon_read_string(struct device *dev, + enum hwmon_sensor_types type, + u32 attr, int channel, + const char **str) +{ + *str = channel ? "temp" : "temp ambient"; + return 0; +} + +static int +power_supply_hwmon_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *val) +{ + struct power_supply_hwmon *psyhw = dev_get_drvdata(dev); + struct power_supply *psy = psyhw->psy; + union power_supply_propval pspval; + int ret, prop; + + prop = power_supply_hwmon_to_property(type, attr, channel); + if (prop < 0) + return prop; + + ret = power_supply_get_property(psy, prop, &pspval); + if (ret) + return ret; + + switch (type) { + /* + * Both voltage and current is reported in units of + * microvolts/microamps, so we need to adjust it to + * milliamps(volts) + */ + case hwmon_curr: + case hwmon_in: + pspval.intval /= 1000; + break; + /* + * Temp needs to be converted from 1/10 C to milli-C + */ + case hwmon_temp: + pspval.intval *= 100; + break; + default: + break; + } + + *val = pspval.intval; + + return 0; +} + +static int +power_supply_hwmon_write(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long val) +{ + struct power_supply_hwmon *psyhw = dev_get_drvdata(dev); + struct power_supply *psy = psyhw->psy; + union power_supply_propval pspval; + int prop; + + prop = power_supply_hwmon_to_property(type, attr, channel); + if (prop < 0) + return prop; + + pspval.intval = val; + + switch (type) { + /* + * Both voltage and current is reported in units of + * microvolts/microamps, so we need to adjust it to + * milliamps(volts) + */ + case hwmon_curr: + case hwmon_in: + pspval.intval *= 1000; + break; + /* + * Temp needs to be converted from 1/10 C to milli-C + */ + case hwmon_temp: + pspval.intval /= 100; + break; + default: + break; + } + + return power_supply_set_property(psy, prop, &pspval); +} + +static const struct hwmon_ops power_supply_hwmon_ops = { + .is_visible = power_supply_hwmon_is_visible, + .read = power_supply_hwmon_read, + .write = power_supply_hwmon_write, + .read_string = power_supply_hwmon_read_string, +}; + +static const struct hwmon_channel_info *power_supply_hwmon_info[] = { + HWMON_CHANNEL_INFO(temp, + HWMON_T_LABEL | + HWMON_T_INPUT | + HWMON_T_MAX | + HWMON_T_MIN | + HWMON_T_MIN_ALARM | + HWMON_T_MIN_ALARM, + + HWMON_T_LABEL | + HWMON_T_INPUT | + HWMON_T_MIN_ALARM | + HWMON_T_LABEL | + HWMON_T_MAX_ALARM), + + HWMON_CHANNEL_INFO(curr, + HWMON_C_AVERAGE | + HWMON_C_MAX | + HWMON_C_INPUT), + + HWMON_CHANNEL_INFO(in, + HWMON_I_AVERAGE | + HWMON_I_MIN | + HWMON_I_MAX | + HWMON_I_INPUT), + NULL +}; + +static const struct hwmon_chip_info power_supply_hwmon_chip_info = { + .ops = &power_supply_hwmon_ops, + .info = power_supply_hwmon_info, +}; + +static void power_supply_hwmon_bitmap_free(void *data) +{ + bitmap_free(data); +} + +struct device *devm_power_supply_add_hwmon_sysfs(struct power_supply *psy) +{ + const struct power_supply_desc *desc = psy->desc; + struct power_supply_hwmon *psyhw; + struct device *dev = &psy->dev; + struct device *hwmon; + int ret, i; + + if (!devres_open_group(dev, NULL, GFP_KERNEL)) + return ERR_PTR(-ENOMEM); + + psyhw = devm_kzalloc(dev, sizeof(*psyhw), GFP_KERNEL); + if (!psyhw) { + ret = -ENOMEM; + goto error; + } + + psyhw->psy = psy; + psyhw->props = bitmap_zalloc(POWER_SUPPLY_PROP_TIME_TO_FULL_AVG + 1, + GFP_KERNEL); + if (!psyhw->props) { + ret = -ENOMEM; + goto error; + } + + ret = devm_add_action(dev, power_supply_hwmon_bitmap_free, + psyhw->props); + if (ret) + goto error; + + for (i = 0; i < desc->num_properties; i++) { + const enum power_supply_property prop = desc->properties[i]; + + switch (prop) { + case POWER_SUPPLY_PROP_CURRENT_AVG: + case POWER_SUPPLY_PROP_CURRENT_MAX: + case POWER_SUPPLY_PROP_CURRENT_NOW: + case POWER_SUPPLY_PROP_TEMP: + case POWER_SUPPLY_PROP_TEMP_MAX: + case POWER_SUPPLY_PROP_TEMP_MIN: + case POWER_SUPPLY_PROP_TEMP_ALERT_MIN: + case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: + case POWER_SUPPLY_PROP_TEMP_AMBIENT: + case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN: + case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX: + case POWER_SUPPLY_PROP_VOLTAGE_AVG: + case POWER_SUPPLY_PROP_VOLTAGE_MIN: + case POWER_SUPPLY_PROP_VOLTAGE_MAX: + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + set_bit(prop, psyhw->props); + break; + default: + break; + } + } + + hwmon = devm_hwmon_device_register_with_info(dev, psy->desc->name, + psyhw, + &power_supply_hwmon_chip_info, + NULL); + ret = PTR_ERR_OR_ZERO(hwmon); + if (ret) + goto error; + + devres_remove_group(dev, NULL); + return hwmon; +error: + devres_release_group(dev, NULL); + return ERR_PTR(ret); +} diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index d9c0c094f8a0..839abfa2c640 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -481,4 +481,15 @@ static inline bool power_supply_is_watt_property(enum power_supply_property psp) return 0; } +#ifdef CONFIG_POWER_SUPPLY_HWMON +extern struct device * +devm_power_supply_add_hwmon_sysfs(struct power_supply *psy); +#else +static struct device * +devm_power_supply_add_hwmon_sysfs(struct power_supply *psy) +{ + return 0; +} +#endif + #endif /* __LINUX_POWER_SUPPLY_H__ */ From patchwork Wed May 29 07:11:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Smirnov X-Patchwork-Id: 10966183 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7DD6F76 for ; Wed, 29 May 2019 07:11:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6E04028791 for ; Wed, 29 May 2019 07:11:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 61FE2287A6; Wed, 29 May 2019 07:11:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EC9F728791 for ; Wed, 29 May 2019 07:11:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726576AbfE2HLb (ORCPT ); Wed, 29 May 2019 03:11:31 -0400 Received: from mail-pl1-f195.google.com ([209.85.214.195]:40872 "EHLO mail-pl1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726568AbfE2HLa (ORCPT ); Wed, 29 May 2019 03:11:30 -0400 Received: by mail-pl1-f195.google.com with SMTP id g69so657123plb.7; Wed, 29 May 2019 00:11:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0qigX1mJNTElLHAS9uWeOS6rmTLOEOvDTk1cuKvKYM4=; b=Ex6AyfvK8A1cFi8X4iMds24aE6z3i/KWLhxOPOya0hzGAJzl++SeV8LRbuS2OaxVn9 tmY35aPfTZzQy5pLEKRViYMS2HDWWvAEpHCawxD4w503h65weXl7oGYd4qi0AmmV+azl 13xtQhwA3Q8sq0yybTObP2bs6VqkUsyyfwCEYOqqlCCdKzQQE5CFgFWuF9d4BVw8ltr2 +EXi9OE1jnqhqiIydg1ym6Gg2mDJzHv++spL/OixOjYPk4i289YEyMZdyRgxZnzKKpfq 4zYCd1BlM/UKYsMCZ8Zd2stMdPigCJpDTolSPXzrdMYsclw+U3Z6cxHnVwVyYCGRmfCv 1WAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0qigX1mJNTElLHAS9uWeOS6rmTLOEOvDTk1cuKvKYM4=; b=WDlAdhKcsKPm5Vcu8aWFmF5KMDL3ecZyDWiIRXEJsaB/wYNQrizUzuND6vjecTaQbM 4EOGj2nukh3tLMItVUTVelnJMfMijrTsn36r8JBHzQho/oszRECqoaN5aVyke2hdRtBV r/Hkr7h5bcSo5mdydSZJH9TIk0yNW/J+Av6C/Thw1T+ATlm/7KqF46DIDgZ1GI265N5g urQgeXkBIDnn09FGbwj4ga8JKPB5FziVI+Ur0EF11+kseowGVdXZvpMsy56Pl1u9aCfv Sjajo2NQFZzdYuxBLBLmdsZu2bP29+6Tk5t35C5e0vqYr1gT0XxvGOCvg03+l9ll0Men Vucg== X-Gm-Message-State: APjAAAWfPnqc5xWr+z5pvwPHvrDosesWbyVHp4Xi1Tc00YWy+9yb+t7E F4m4Rk30h9DRPDFfutQP1Jgh3+qXlK4= X-Google-Smtp-Source: APXvYqx8FD5B0sMQ8Jni2x7WsXqeLZatQCCizEvafp2Qq4ANhjXD+zILaltPXLv9vbhdXmofYrt2qw== X-Received: by 2002:a17:902:e40f:: with SMTP id ci15mr142351041plb.280.1559113889861; Wed, 29 May 2019 00:11:29 -0700 (PDT) Received: from localhost.lan (c-24-22-235-96.hsd1.wa.comcast.net. [24.22.235.96]) by smtp.gmail.com with ESMTPSA id u20sm18083307pfm.145.2019.05.29.00.11.28 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 29 May 2019 00:11:29 -0700 (PDT) From: Andrey Smirnov To: linux-pm@vger.kernel.org Cc: Andrey Smirnov , Chris Healy , Lucas Stach , Fabio Estevam , Guenter Roeck , Sebastian Reichel , linux-kernel@vger.kernel.org Subject: [PATCH 2/2] power: supply: ucs1002: Add HWMON interface Date: Wed, 29 May 2019 00:11:12 -0700 Message-Id: <20190529071112.16849-3-andrew.smirnov@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190529071112.16849-1-andrew.smirnov@gmail.com> References: <20190529071112.16849-1-andrew.smirnov@gmail.com> MIME-Version: 1.0 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Expose current sensors found on UCS1002 via HWMON. Signed-off-by: Andrey Smirnov Cc: Chris Healy Cc: Lucas Stach Cc: Fabio Estevam Cc: Guenter Roeck Cc: Sebastian Reichel Cc: linux-kernel@vger.kernel.org Cc: linux-pm@vger.kernel.org --- drivers/power/supply/ucs1002_power.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/ucs1002_power.c b/drivers/power/supply/ucs1002_power.c index 1c89d030c045..1faf2ef7d3f0 100644 --- a/drivers/power/supply/ucs1002_power.c +++ b/drivers/power/supply/ucs1002_power.c @@ -491,7 +491,7 @@ static const struct regulator_desc ucs1002_regulator_descriptor = { static int ucs1002_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) { - struct device *dev = &client->dev; + struct device *hwmon, *dev = &client->dev; struct power_supply_config charger_config = {}; const struct regmap_config regmap_config = { .reg_bits = 8, @@ -571,6 +571,13 @@ static int ucs1002_probe(struct i2c_client *client, return ret; } + hwmon = devm_power_supply_add_hwmon_sysfs(info->charger); + ret = PTR_ERR_OR_ZERO(hwmon); + if (ret) { + dev_err(dev, "Failed to add hmwon attributes: %d\n", ret); + return ret; + } + ret = regmap_read(info->regmap, UCS1002_REG_PIN_STATUS, ®val); if (ret) { dev_err(dev, "Failed to read pin status: %d\n", ret);