Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp3396943ybl; Mon, 27 Jan 2020 03:17:34 -0800 (PST) X-Google-Smtp-Source: APXvYqwIP4pMicQj7ozE3Y/U/DgWGXb2ppMz0nfRlVFKHMvpb/GHz5GRtLze3BWixPeJFDuML8PM X-Received: by 2002:a9d:2c2:: with SMTP id 60mr12092765otl.208.1580123853604; Mon, 27 Jan 2020 03:17:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1580123853; cv=none; d=google.com; s=arc-20160816; b=jPnpAYgKfW67yi3kk272Hw5NrTUIU30qc8Hg2oBYyV000fNVZX2d/33Gj3Lu8nwaNf zL3n7ps0NjWWAbwsnfpJxsx5TmoPlNqw0d5k1JD3Bob0sycqJDC8cp9LFjHWc9gIYSkl MSEwBLxZBbsdrDOye1OlToY3w4C59u5o+GOmW4wk5Y7eB6rBoKGi8aB5TFdfeuKIIHx4 aiKKWcHLYIXerK/Aw+O9uyz34/W1zDU6A2SAUmGQzLMuUnOmYQ8gIM3Kh35hPQEryD2y DIoxwlnsjBp1jIIbi8uAtu+sl0FzjVCFrU52HKcR1WQzyjOKMxt/Pe5EFFdvR2RE7gKh OrKw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=2QfB1kEoo91e4m25/t0vua7LN1BCBNv7PlbhLQBcnZA=; b=SWeqRcPXQrjenStHyCUH0qCmpulys3TZpYhxNT5mKfN/HAJUxbbZ0AhBLomuMQXcJm ZRbA7vcg3fPeHUOy15u9leuj8yo3NpSIHwHtTYB2qq5rIkMSDMwoRjG2ndVgeKmRggbD NYkhYFCNpA3kMNX3Dqu4MOMqewRP1o6+5IM3gE90Vux7Ab6psclqDolvUjLk5OkIdAGG vwnLDPcbjC0HGv/DwmPLgBGRqAFxzvrfU6Fr2DQNovGExVMhLCq0dxAbQ/o8JqaVPF0q 5fOktv6MQHVvFZKEe/vXub/fDKnT3VST6wFPzzVeFvQKwifB2dqcACxjAbyTljYXtO+I zcHA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v11si3338797otp.279.2020.01.27.03.17.21; Mon, 27 Jan 2020 03:17:33 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729450AbgA0KZu (ORCPT + 99 others); Mon, 27 Jan 2020 05:25:50 -0500 Received: from metis.ext.pengutronix.de ([85.220.165.71]:37939 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728386AbgA0KZt (ORCPT ); Mon, 27 Jan 2020 05:25:49 -0500 Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1iw1aR-0002BE-4Y; Mon, 27 Jan 2020 11:25:43 +0100 Received: from ore by dude.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1iw1aQ-0008Qr-8O; Mon, 27 Jan 2020 11:25:42 +0100 From: Oleksij Rempel To: Jean Delvare , Markus Pietrek , Guenter Roeck Cc: Oleksij Rempel , kernel@pengutronix.de, linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH V1 2/2] hwmon: (powr1220) add scaled voltage support Date: Mon, 27 Jan 2020 11:25:40 +0100 Message-Id: <20200127102540.31742-2-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200127102540.31742-1-o.rempel@pengutronix.de> References: <20200127102540.31742-1-o.rempel@pengutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Markus Pietrek On some (or may be all?) boards, voltage measured by powr1220 do not reflect real system configuration. This patch provides scale option to set board specific configuration. Signed-off-by: Markus Pietrek Signed-off-by: Oleksij Rempel --- drivers/hwmon/powr1220.c | 155 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) diff --git a/drivers/hwmon/powr1220.c b/drivers/hwmon/powr1220.c index ad7a82f132e6..7cb2a6d3b3d8 100644 --- a/drivers/hwmon/powr1220.c +++ b/drivers/hwmon/powr1220.c @@ -74,6 +74,14 @@ enum powr1220_adc_values { MAX_POWR1220_ADC_VALUES }; +/* Real value = (measured-value * factor) / divisor. + * A divisor of 0 disables scaling and is identical to factor==1 && divisor==1. + */ +struct adc_scale { + int factor; + int divisor; +}; + struct powr1220_data { struct i2c_client *client; struct mutex update_lock; @@ -84,6 +92,7 @@ struct powr1220_data { /* values */ int adc_maxes[MAX_POWR1220_ADC_VALUES]; int adc_values[MAX_POWR1220_ADC_VALUES]; + struct adc_scale adc_scales[MAX_POWR1220_ADC_VALUES]; }; static const char * const input_names[] = { @@ -184,6 +193,29 @@ static ssize_t powr1220_voltage_show(struct device *dev, return sprintf(buf, "%d\n", adc_val); } +static ssize_t powr1220_scaled_voltage_show(struct device *dev, + struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct powr1220_data *data = dev_get_drvdata(dev); + int adc_val = powr1220_read_adc(dev, attr->index); + struct adc_scale *scale; + + if (adc_val < 0) + return adc_val; + + scale = &data->adc_scales[attr->index]; + if (scale->divisor) { + int64_t lscaled = adc_val; + + lscaled *= scale->factor; + lscaled /= scale->divisor; + adc_val = (int) lscaled; + } + + return sprintf(buf, "%d\n", adc_val); +} + /* Shows the maximum setting associated with the specified ADC channel */ static ssize_t powr1220_max_show(struct device *dev, struct device_attribute *dev_attr, char *buf) @@ -204,6 +236,38 @@ static ssize_t powr1220_label_show(struct device *dev, return sprintf(buf, "%s\n", input_names[attr->index]); } +/* Shows the scale for the read value. + * real value = (measured value * factor) / divisor. n/0 means scaling disabled + * and raw values are printed. + */ +static ssize_t powr1220_scale_show(struct device *dev, + struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct powr1220_data *data = dev_get_drvdata(dev); + + return sprintf(buf, "%d/%d\n", data->adc_scales[attr->index].factor, + data->adc_scales[attr->index].divisor); +} + +static ssize_t powr1220_scale_store(struct device *dev, + struct device_attribute *dev_attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct powr1220_data *data = dev_get_drvdata(dev); + int factor; + int divisor; + + if (sscanf(buf, "%d/%d", &factor, &divisor) != 2) + return -EINVAL; + + data->adc_scales[attr->index].factor = factor; + data->adc_scales[attr->index].divisor = divisor; + + return count; +} + static SENSOR_DEVICE_ATTR_RO(in0_input, powr1220_voltage, VMON1); static SENSOR_DEVICE_ATTR_RO(in1_input, powr1220_voltage, VMON2); static SENSOR_DEVICE_ATTR_RO(in2_input, powr1220_voltage, VMON3); @@ -219,6 +283,26 @@ static SENSOR_DEVICE_ATTR_RO(in11_input, powr1220_voltage, VMON12); static SENSOR_DEVICE_ATTR_RO(in12_input, powr1220_voltage, VCCA); static SENSOR_DEVICE_ATTR_RO(in13_input, powr1220_voltage, VCCINP); +static SENSOR_DEVICE_ATTR_RO(in0_scaled_input, powr1220_scaled_voltage, VMON1); +static SENSOR_DEVICE_ATTR_RO(in1_scaled_input, powr1220_scaled_voltage, VMON2); +static SENSOR_DEVICE_ATTR_RO(in2_scaled_input, powr1220_scaled_voltage, VMON3); +static SENSOR_DEVICE_ATTR_RO(in3_scaled_input, powr1220_scaled_voltage, VMON4); +static SENSOR_DEVICE_ATTR_RO(in4_scaled_input, powr1220_scaled_voltage, VMON5); +static SENSOR_DEVICE_ATTR_RO(in5_scaled_input, powr1220_scaled_voltage, VMON6); +static SENSOR_DEVICE_ATTR_RO(in6_scaled_input, powr1220_scaled_voltage, VMON7); +static SENSOR_DEVICE_ATTR_RO(in7_scaled_input, powr1220_scaled_voltage, VMON8); +static SENSOR_DEVICE_ATTR_RO(in8_scaled_input, powr1220_scaled_voltage, VMON9); +static SENSOR_DEVICE_ATTR_RO(in9_scaled_input, powr1220_scaled_voltage, + VMON10); +static SENSOR_DEVICE_ATTR_RO(in10_scaled_input, powr1220_scaled_voltage, + VMON11); +static SENSOR_DEVICE_ATTR_RO(in11_scaled_input, powr1220_scaled_voltage, + VMON12); +static SENSOR_DEVICE_ATTR_RO(in12_scaled_input, powr1220_scaled_voltage, + VCCA); +static SENSOR_DEVICE_ATTR_RO(in13_scaled_input, powr1220_scaled_voltage, + VCCINP); + static SENSOR_DEVICE_ATTR_RO(in0_highest, powr1220_max, VMON1); static SENSOR_DEVICE_ATTR_RO(in1_highest, powr1220_max, VMON2); static SENSOR_DEVICE_ATTR_RO(in2_highest, powr1220_max, VMON3); @@ -249,6 +333,21 @@ static SENSOR_DEVICE_ATTR_RO(in11_label, powr1220_label, VMON12); static SENSOR_DEVICE_ATTR_RO(in12_label, powr1220_label, VCCA); static SENSOR_DEVICE_ATTR_RO(in13_label, powr1220_label, VCCINP); +static SENSOR_DEVICE_ATTR_RW(in0_scale, powr1220_scale, VMON1); +static SENSOR_DEVICE_ATTR_RW(in1_scale, powr1220_scale, VMON2); +static SENSOR_DEVICE_ATTR_RW(in2_scale, powr1220_scale, VMON3); +static SENSOR_DEVICE_ATTR_RW(in3_scale, powr1220_scale, VMON4); +static SENSOR_DEVICE_ATTR_RW(in4_scale, powr1220_scale, VMON5); +static SENSOR_DEVICE_ATTR_RW(in5_scale, powr1220_scale, VMON6); +static SENSOR_DEVICE_ATTR_RW(in6_scale, powr1220_scale, VMON7); +static SENSOR_DEVICE_ATTR_RW(in7_scale, powr1220_scale, VMON8); +static SENSOR_DEVICE_ATTR_RW(in8_scale, powr1220_scale, VMON9); +static SENSOR_DEVICE_ATTR_RW(in9_scale, powr1220_scale, VMON10); +static SENSOR_DEVICE_ATTR_RW(in10_scale, powr1220_scale, VMON11); +static SENSOR_DEVICE_ATTR_RW(in11_scale, powr1220_scale, VMON12); +static SENSOR_DEVICE_ATTR_RW(in12_scale, powr1220_scale, VCCA); +static SENSOR_DEVICE_ATTR_RW(in13_scale, powr1220_scale, VCCINP); + static struct attribute *powr1014_attrs[] = { &sensor_dev_attr_in0_input.dev_attr.attr, &sensor_dev_attr_in1_input.dev_attr.attr, @@ -263,6 +362,19 @@ static struct attribute *powr1014_attrs[] = { &sensor_dev_attr_in12_input.dev_attr.attr, &sensor_dev_attr_in13_input.dev_attr.attr, + &sensor_dev_attr_in0_scaled_input.dev_attr.attr, + &sensor_dev_attr_in1_scaled_input.dev_attr.attr, + &sensor_dev_attr_in2_scaled_input.dev_attr.attr, + &sensor_dev_attr_in3_scaled_input.dev_attr.attr, + &sensor_dev_attr_in4_scaled_input.dev_attr.attr, + &sensor_dev_attr_in5_scaled_input.dev_attr.attr, + &sensor_dev_attr_in6_scaled_input.dev_attr.attr, + &sensor_dev_attr_in7_scaled_input.dev_attr.attr, + &sensor_dev_attr_in8_scaled_input.dev_attr.attr, + &sensor_dev_attr_in9_scaled_input.dev_attr.attr, + &sensor_dev_attr_in12_scaled_input.dev_attr.attr, + &sensor_dev_attr_in13_scaled_input.dev_attr.attr, + &sensor_dev_attr_in0_highest.dev_attr.attr, &sensor_dev_attr_in1_highest.dev_attr.attr, &sensor_dev_attr_in2_highest.dev_attr.attr, @@ -289,6 +401,19 @@ static struct attribute *powr1014_attrs[] = { &sensor_dev_attr_in12_label.dev_attr.attr, &sensor_dev_attr_in13_label.dev_attr.attr, + &sensor_dev_attr_in0_scale.dev_attr.attr, + &sensor_dev_attr_in1_scale.dev_attr.attr, + &sensor_dev_attr_in2_scale.dev_attr.attr, + &sensor_dev_attr_in3_scale.dev_attr.attr, + &sensor_dev_attr_in4_scale.dev_attr.attr, + &sensor_dev_attr_in5_scale.dev_attr.attr, + &sensor_dev_attr_in6_scale.dev_attr.attr, + &sensor_dev_attr_in7_scale.dev_attr.attr, + &sensor_dev_attr_in8_scale.dev_attr.attr, + &sensor_dev_attr_in9_scale.dev_attr.attr, + &sensor_dev_attr_in12_scale.dev_attr.attr, + &sensor_dev_attr_in13_scale.dev_attr.attr, + NULL }; @@ -310,6 +435,21 @@ static struct attribute *powr1220_attrs[] = { &sensor_dev_attr_in12_input.dev_attr.attr, &sensor_dev_attr_in13_input.dev_attr.attr, + &sensor_dev_attr_in0_scaled_input.dev_attr.attr, + &sensor_dev_attr_in1_scaled_input.dev_attr.attr, + &sensor_dev_attr_in2_scaled_input.dev_attr.attr, + &sensor_dev_attr_in3_scaled_input.dev_attr.attr, + &sensor_dev_attr_in4_scaled_input.dev_attr.attr, + &sensor_dev_attr_in5_scaled_input.dev_attr.attr, + &sensor_dev_attr_in6_scaled_input.dev_attr.attr, + &sensor_dev_attr_in7_scaled_input.dev_attr.attr, + &sensor_dev_attr_in8_scaled_input.dev_attr.attr, + &sensor_dev_attr_in9_scaled_input.dev_attr.attr, + &sensor_dev_attr_in10_scaled_input.dev_attr.attr, + &sensor_dev_attr_in11_scaled_input.dev_attr.attr, + &sensor_dev_attr_in12_scaled_input.dev_attr.attr, + &sensor_dev_attr_in13_scaled_input.dev_attr.attr, + &sensor_dev_attr_in0_highest.dev_attr.attr, &sensor_dev_attr_in1_highest.dev_attr.attr, &sensor_dev_attr_in2_highest.dev_attr.attr, @@ -340,6 +480,21 @@ static struct attribute *powr1220_attrs[] = { &sensor_dev_attr_in12_label.dev_attr.attr, &sensor_dev_attr_in13_label.dev_attr.attr, + &sensor_dev_attr_in0_scale.dev_attr.attr, + &sensor_dev_attr_in1_scale.dev_attr.attr, + &sensor_dev_attr_in2_scale.dev_attr.attr, + &sensor_dev_attr_in3_scale.dev_attr.attr, + &sensor_dev_attr_in4_scale.dev_attr.attr, + &sensor_dev_attr_in5_scale.dev_attr.attr, + &sensor_dev_attr_in6_scale.dev_attr.attr, + &sensor_dev_attr_in7_scale.dev_attr.attr, + &sensor_dev_attr_in8_scale.dev_attr.attr, + &sensor_dev_attr_in9_scale.dev_attr.attr, + &sensor_dev_attr_in10_scale.dev_attr.attr, + &sensor_dev_attr_in11_scale.dev_attr.attr, + &sensor_dev_attr_in12_scale.dev_attr.attr, + &sensor_dev_attr_in13_scale.dev_attr.attr, + NULL }; -- 2.25.0