public inbox for linux-hwmon@vger.kernel.org
 help / color / mirror / Atom feed
From: Guenter Roeck <linux@roeck-us.net>
To: Andrew Jeffery <andrew@aj.id.au>
Cc: linux-hwmon@vger.kernel.org, jdelvare@suse.com, corbet@lwn.net,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-doc@vger.kernel.org, joel@jms.id.au,
	openbmc@lists.ozlabs.org
Subject: Re: [v6,2/4] pmbus (max31785): Add fan control
Date: Wed, 29 Nov 2017 13:13:05 -0800	[thread overview]
Message-ID: <20171129211305.GA22082@roeck-us.net> (raw)
In-Reply-To: <8c06a1a1fcb67745fb9015b5c3f69f6f12ae0b0f.1511152748.git-series.andrew@aj.id.au>

On Mon, Nov 20, 2017 at 03:12:04PM +1030, Andrew Jeffery wrote:
> The implementation makes use of the new fan control virtual registers
> exposed by the pmbus core. It mixes use of the default implementations
> with some overrides via the read/write handlers to handle FAN_COMMAND_1
> on the MAX31785, whose definition breaks the value range into various
> control bands dependent on RPM or PWM mode.
> 
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

Applied.

Thanks,
Guenter

> ---
>  Documentation/hwmon/max31785   |   7 ++-
>  drivers/hwmon/pmbus/max31785.c | 138 +++++++++++++++++++++++++++++++++-
>  2 files changed, 144 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/hwmon/max31785 b/Documentation/hwmon/max31785
> index 45fb6093dec2..7b0a0a8cdb6b 100644
> --- a/Documentation/hwmon/max31785
> +++ b/Documentation/hwmon/max31785
> @@ -32,6 +32,7 @@ Sysfs attributes
>  fan[1-4]_alarm		Fan alarm.
>  fan[1-4]_fault		Fan fault.
>  fan[1-4]_input		Fan RPM.
> +fan[1-4]_target		Fan input target
>  
>  in[1-6]_crit		Critical maximum output voltage
>  in[1-6]_crit_alarm	Output voltage critical high alarm
> @@ -44,6 +45,12 @@ in[1-6]_max_alarm	Output voltage high alarm
>  in[1-6]_min		Minimum output voltage
>  in[1-6]_min_alarm	Output voltage low alarm
>  
> +pwm[1-4]		Fan target duty cycle (0..255)
> +pwm[1-4]_enable		0: Full-speed
> +			1: Manual PWM control
> +			2: Automatic PWM (tach-feedback RPM fan-control)
> +			3: Automatic closed-loop (temp-feedback fan-control)
> +
>  temp[1-11]_crit		Critical high temperature
>  temp[1-11]_crit_alarm	Chip temperature critical high alarm
>  temp[1-11]_input	Measured temperature
> diff --git a/drivers/hwmon/pmbus/max31785.c b/drivers/hwmon/pmbus/max31785.c
> index 9313849d5160..8706a696c89a 100644
> --- a/drivers/hwmon/pmbus/max31785.c
> +++ b/drivers/hwmon/pmbus/max31785.c
> @@ -20,8 +20,136 @@ enum max31785_regs {
>  
>  #define MAX31785_NR_PAGES		23
>  
> +static int max31785_get_pwm(struct i2c_client *client, int page)
> +{
> +	int rv;
> +
> +	rv = pmbus_get_fan_rate_device(client, page, 0, percent);
> +	if (rv < 0)
> +		return rv;
> +	else if (rv >= 0x8000)
> +		return 0;
> +	else if (rv >= 0x2711)
> +		return 0x2710;
> +
> +	return rv;
> +}
> +
> +static int max31785_get_pwm_mode(struct i2c_client *client, int page)
> +{
> +	int config;
> +	int command;
> +
> +	config = pmbus_read_byte_data(client, page, PMBUS_FAN_CONFIG_12);
> +	if (config < 0)
> +		return config;
> +
> +	command = pmbus_read_word_data(client, page, PMBUS_FAN_COMMAND_1);
> +	if (command < 0)
> +		return command;
> +
> +	if (config & PB_FAN_1_RPM)
> +		return (command >= 0x8000) ? 3 : 2;
> +
> +	if (command >= 0x8000)
> +		return 3;
> +	else if (command >= 0x2711)
> +		return 0;
> +
> +	return 1;
> +}
> +
> +static int max31785_read_word_data(struct i2c_client *client, int page,
> +				   int reg)
> +{
> +	int rv;
> +
> +	switch (reg) {
> +	case PMBUS_VIRT_PWM_1:
> +		rv = max31785_get_pwm(client, page);
> +		break;
> +	case PMBUS_VIRT_PWM_ENABLE_1:
> +		rv = max31785_get_pwm_mode(client, page);
> +		break;
> +	default:
> +		rv = -ENODATA;
> +		break;
> +	}
> +
> +	return rv;
> +}
> +
> +static inline u32 max31785_scale_pwm(u32 sensor_val)
> +{
> +	/*
> +	 * The datasheet describes the accepted value range for manual PWM as
> +	 * [0, 0x2710], while the hwmon pwmX sysfs interface accepts values in
> +	 * [0, 255]. The MAX31785 uses DIRECT mode to scale the FAN_COMMAND
> +	 * registers and in PWM mode the coefficients are m=1, b=0, R=2. The
> +	 * important observation here is that 0x2710 == 10000 == 100 * 100.
> +	 *
> +	 * R=2 (== 10^2 == 100) accounts for scaling the value provided at the
> +	 * sysfs interface into the required hardware resolution, but it does
> +	 * not yet yield a value that we can write to the device (this initial
> +	 * scaling is handled by pmbus_data2reg()). Multiplying by 100 below
> +	 * translates the parameter value into the percentage units required by
> +	 * PMBus, and then we scale back by 255 as required by the hwmon pwmX
> +	 * interface to yield the percentage value at the appropriate
> +	 * resolution for hardware.
> +	 */
> +	return (sensor_val * 100) / 255;
> +}
> +
> +static int max31785_pwm_enable(struct i2c_client *client, int page,
> +				    u16 word)
> +{
> +	int config = 0;
> +	int rate;
> +
> +	switch (word) {
> +	case 0:
> +		rate = 0x7fff;
> +		break;
> +	case 1:
> +		rate = pmbus_get_fan_rate_cached(client, page, 0, percent);
> +		if (rate < 0)
> +			return rate;
> +		rate = max31785_scale_pwm(rate);
> +		break;
> +	case 2:
> +		config = PB_FAN_1_RPM;
> +		rate = pmbus_get_fan_rate_cached(client, page, 0, rpm);
> +		if (rate < 0)
> +			return rate;
> +		break;
> +	case 3:
> +		rate = 0xffff;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return pmbus_update_fan(client, page, 0, config, PB_FAN_1_RPM, rate);
> +}
> +
> +static int max31785_write_word_data(struct i2c_client *client, int page,
> +				    int reg, u16 word)
> +{
> +	switch (reg) {
> +	case PMBUS_VIRT_PWM_1:
> +		return pmbus_update_fan(client, page, 0, 0, PB_FAN_1_RPM,
> +					max31785_scale_pwm(word));
> +	case PMBUS_VIRT_PWM_ENABLE_1:
> +		return max31785_pwm_enable(client, page, word);
> +	default:
> +		break;
> +	}
> +
> +	return -ENODATA;
> +}
> +
>  #define MAX31785_FAN_FUNCS \
> -	(PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12)
> +	(PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12 | PMBUS_HAVE_PWM12)
>  
>  #define MAX31785_TEMP_FUNCS \
>  	(PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP)
> @@ -32,11 +160,19 @@ enum max31785_regs {
>  static const struct pmbus_driver_info max31785_info = {
>  	.pages = MAX31785_NR_PAGES,
>  
> +	.write_word_data = max31785_write_word_data,
> +	.read_word_data = max31785_read_word_data,
> +
>  	/* RPM */
>  	.format[PSC_FAN] = direct,
>  	.m[PSC_FAN] = 1,
>  	.b[PSC_FAN] = 0,
>  	.R[PSC_FAN] = 0,
> +	/* PWM */
> +	.format[PSC_PWM] = direct,
> +	.m[PSC_PWM] = 1,
> +	.b[PSC_PWM] = 0,
> +	.R[PSC_PWM] = 2,
>  	.func[0] = MAX31785_FAN_FUNCS,
>  	.func[1] = MAX31785_FAN_FUNCS,
>  	.func[2] = MAX31785_FAN_FUNCS,

  reply	other threads:[~2017-11-29 21:13 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-20  4:42 [PATCH v6 0/4] pmbus: Expand fan support and add MAX31785 driver Andrew Jeffery
2017-11-20  4:42 ` [PATCH v6 1/4] pmbus (core): Add fan control support Andrew Jeffery
2017-11-29 21:10   ` [v6,1/4] " Guenter Roeck
2017-11-20  4:42 ` [PATCH v6 2/4] pmbus (max31785): Add fan control Andrew Jeffery
2017-11-29 21:13   ` Guenter Roeck [this message]
2017-11-20  4:42 ` [PATCH v6 3/4] pmbus (core): Add virtual page config bit Andrew Jeffery
2017-11-29 21:15   ` [v6,3/4] " Guenter Roeck
2017-11-20  4:42 ` [PATCH v6 4/4] pmbus (max31785): Add dual tachometer support Andrew Jeffery
2017-11-29 21:17   ` [v6,4/4] " Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171129211305.GA22082@roeck-us.net \
    --to=linux@roeck-us.net \
    --cc=andrew@aj.id.au \
    --cc=corbet@lwn.net \
    --cc=devicetree@vger.kernel.org \
    --cc=jdelvare@suse.com \
    --cc=joel@jms.id.au \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-hwmon@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=openbmc@lists.ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox