[PATCH v6 2/4] pmbus (max31785): Add fan control

2017-11-19 Thread Andrew Jeffery
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 
---
 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]_targetFan 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_alarmOutput voltage high alarm
 in[1-6]_minMinimum output voltage
 in[1-6]_min_alarm  Output voltage low alarm
 
+pwm[1-4]   Fan target duty cycle (0..255)
+pwm[1-4]_enable0: 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]_critCritical 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 == 1 == 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:
+ 

[PATCH v6 3/4] pmbus (core): Add virtual page config bit

2017-11-19 Thread Andrew Jeffery
Some circumstances call for virtual pages, to expose multiple values
packed into an extended PMBus register in a manner non-compliant with
the PMBus standard. An example of this is the Maxim MAX31785 controller, which
extends the READ_FAN_SPEED_1 PMBus register from two to four bytes to support
tach readings for both rotors of a dual rotor fan. This extended register
contains two word-sized values, one reporting the rate of the fastest rotor,
the other the rate of the slowest. The concept of virtual pages aids this
situation by mapping the page number onto the value to be selected from the
vectored result.

We should not try to set virtual pages on the device as such a page explicitly
doesn't exist; add a flag so we can avoid doing so.

Signed-off-by: Andrew Jeffery 
---
 drivers/hwmon/pmbus/pmbus.h  |  2 ++
 drivers/hwmon/pmbus/pmbus_core.c | 27 ++-
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h
index b54d7604d3ef..d39d506aa63e 100644
--- a/drivers/hwmon/pmbus/pmbus.h
+++ b/drivers/hwmon/pmbus/pmbus.h
@@ -372,6 +372,8 @@ enum pmbus_sensor_classes {
 #define PMBUS_HAVE_PWM12   BIT(20)
 #define PMBUS_HAVE_PWM34   BIT(21)
 
+#define PMBUS_PAGE_VIRTUAL BIT(31)
+
 enum pmbus_data_format { linear = 0, direct, vid };
 enum vrm_version { vr11 = 0, vr12, vr13 };
 
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index edc25efe7552..e215bbd403a5 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -161,18 +161,27 @@ EXPORT_SYMBOL_GPL(pmbus_clear_cache);
 int pmbus_set_page(struct i2c_client *client, int page)
 {
struct pmbus_data *data = i2c_get_clientdata(client);
-   int rv = 0;
-   int newpage;
+   int rv;
+
+   if (page < 0 || page == data->currpage)
+   return 0;
 
-   if (page >= 0 && page != data->currpage) {
+   if (!(data->info->func[page] & PMBUS_PAGE_VIRTUAL)) {
rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
-   newpage = i2c_smbus_read_byte_data(client, PMBUS_PAGE);
-   if (newpage != page)
-   rv = -EIO;
-   else
-   data->currpage = page;
+   if (rv < 0)
+   return rv;
+
+   rv = i2c_smbus_read_byte_data(client, PMBUS_PAGE);
+   if (rv < 0)
+   return rv;
+
+   if (rv != page)
+   return -EIO;
}
-   return rv;
+
+   data->currpage = page;
+
+   return 0;
 }
 EXPORT_SYMBOL_GPL(pmbus_set_page);
 
-- 
git-series 0.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-hwmon" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 4/4] pmbus (max31785): Add dual tachometer support

2017-11-19 Thread Andrew Jeffery
The dual tachometer feature is implemented in hardware with a TACHSEL
input to indicate the rotor under measurement, and exposed on the device
by extending the READ_FAN_SPEED_1 word with two extra bytes*. The need
to read the non-standard four-byte response leads to a cut-down
implementation of i2c_smbus_xfer_emulated() included in the driver.
Further, to expose the second rotor tachometer value to userspace the
values are exposed through virtual pages. We re-route accesses to
FAN_CONFIG_1_2 and READ_FAN_SPEED_1 on pages 23-28 (not defined by the
hardware) to the same registers on pages 0-5, and with the latter command we
extract the value from the second word of the four-byte response.

* The documentation recommends the slower rotor be associated with
TACHSEL=0, which corresponds to the first word of the response. The TACHSEL=0
measurement is used by the controller's closed-loop fan management to judge
target fan rate.

Signed-off-by: Andrew Jeffery 
---
 Documentation/hwmon/max31785   |   8 +-
 drivers/hwmon/pmbus/max31785.c | 147 ++-
 2 files changed, 152 insertions(+), 3 deletions(-)

diff --git a/Documentation/hwmon/max31785 b/Documentation/hwmon/max31785
index 7b0a0a8cdb6b..270c5f865261 100644
--- a/Documentation/hwmon/max31785
+++ b/Documentation/hwmon/max31785
@@ -17,8 +17,9 @@ management with temperature and remote voltage sensing. 
Various fan control
 features are provided, including PWM frequency control, temperature hysteresis,
 dual tachometer measurements, and fan health monitoring.
 
-For dual rotor fan configuration, the MAX31785 exposes the slowest rotor of the
-two in the fan[1-4]_input attributes.
+For dual-rotor configurations the MAX31785A exposes the second rotor tachometer
+readings in attributes fan[5-8]_input. By contrast the MAX31785 only exposes
+the slowest rotor measurement, and does so in the fan[1-4]_input attributes.
 
 Usage Notes
 ---
@@ -31,7 +32,8 @@ Sysfs attributes
 
 fan[1-4]_alarm Fan alarm.
 fan[1-4]_fault Fan fault.
-fan[1-4]_input Fan RPM.
+fan[1-8]_input Fan RPM. On the MAX31785A, inputs 5-8 correspond to the
+   second rotor of fans 1-4
 fan[1-4]_targetFan input target
 
 in[1-6]_crit   Critical maximum output voltage
diff --git a/drivers/hwmon/pmbus/max31785.c b/drivers/hwmon/pmbus/max31785.c
index 8706a696c89a..bffab449be39 100644
--- a/drivers/hwmon/pmbus/max31785.c
+++ b/drivers/hwmon/pmbus/max31785.c
@@ -16,9 +16,79 @@
 
 enum max31785_regs {
MFR_REVISION= 0x9b,
+   MFR_FAN_CONFIG  = 0xf1,
 };
 
+#define MAX31785   0x3030
+#define MAX31785A  0x3040
+
+#define MFR_FAN_CONFIG_DUAL_TACH   BIT(12)
+
 #define MAX31785_NR_PAGES  23
+#define MAX31785_NR_FAN_PAGES  6
+
+static int max31785_read_byte_data(struct i2c_client *client, int page,
+  int reg)
+{
+   if (page < MAX31785_NR_PAGES)
+   return -ENODATA;
+
+   switch (reg) {
+   case PMBUS_VOUT_MODE:
+   return -ENOTSUPP;
+   case PMBUS_FAN_CONFIG_12:
+   return pmbus_read_byte_data(client, page - MAX31785_NR_PAGES,
+   reg);
+   }
+
+   return -ENODATA;
+}
+
+static int max31785_write_byte(struct i2c_client *client, int page, u8 value)
+{
+   if (page < MAX31785_NR_PAGES)
+   return -ENODATA;
+
+   return -ENOTSUPP;
+}
+
+static int max31785_read_long_data(struct i2c_client *client, int page,
+  int reg, u32 *data)
+{
+   unsigned char cmdbuf[1];
+   unsigned char rspbuf[4];
+   int rc;
+
+   struct i2c_msg msg[2] = {
+   {
+   .addr = client->addr,
+   .flags = 0,
+   .len = sizeof(cmdbuf),
+   .buf = cmdbuf,
+   },
+   {
+   .addr = client->addr,
+   .flags = I2C_M_RD,
+   .len = sizeof(rspbuf),
+   .buf = rspbuf,
+   },
+   };
+
+   cmdbuf[0] = reg;
+
+   rc = pmbus_set_page(client, page);
+   if (rc < 0)
+   return rc;
+
+   rc = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
+   if (rc < 0)
+   return rc;
+
+   *data = (rspbuf[0] << (0 * 8)) | (rspbuf[1] << (1 * 8)) |
+   (rspbuf[2] << (2 * 8)) | (rspbuf[3] << (3 * 8));
+
+   return rc;
+}
 
 static int max31785_get_pwm(struct i2c_client *client, int page)
 {
@@ -62,9 +132,30 @@ static int max31785_get_pwm_mode(struct i2c_client *client, 
int page)
 static int max31785_read_word_data(struct i2c_client *client, int page,
   int reg)
 {
+   u32 val;
int rv;
 
switch (reg) {
+   case 

[PATCH v6 0/4] pmbus: Expand fan support and add MAX31785 driver

2017-11-19 Thread Andrew Jeffery
Hello,

This series introduces support for the MAX31785 intelligent fan controller, a
PMBus device providing closed-loop fan control among a number of other
features. Along the way the series adds support to control fans and create
virtual pages to the PMBus core, the latter to support some of the more
annoying design decisions found in the 'A' variant of the chip.

This is the sixth spin of the series. v5 can be found here:

https://lkml.org/lkml/2017/11/17/910

v6 fixes an error-handling bug I introduced in pmbus_set_page() with PATCH 3/4,
as pointed out by Guenter on v5[1]. The rework implements his suggested
solution.

A few other other minor fixes are included:

* PATCH 1/4:
  * Avoid potential NULL dereference in pmbus_get_fan_rate(). It
amounts to being an error path that should never happen in practice, but
lets make sure we don't die if we do hit it.
  * Drop a redundant test for the presence of FAN_COMMAND_x in
pmbus_add_fan_ctrl(); document that its presence is a precondition to
calling it (this was already tested at the one call-site).

* PATCH 2/4: Avoid scaling an error code in pmbus_pwm_enable(). Rather, test
  the result of pmbus_get_fan_rate_cached() before performing the scaling when
  switching to PWM mode.

[1] https://lkml.org/lkml/2017/11/19/280

Please review!

Andrew

Andrew Jeffery (4):
  pmbus (core): Add fan control support
  pmbus (max31785): Add fan control
  pmbus (core): Add virtual page config bit
  pmbus (max31785): Add dual tachometer support

 Documentation/hwmon/max31785 |  15 +-
 drivers/hwmon/pmbus/max31785.c   | 285 +++-
 drivers/hwmon/pmbus/pmbus.h  |  41 -
 drivers/hwmon/pmbus/pmbus_core.c | 265 +++---
 4 files changed, 575 insertions(+), 31 deletions(-)

base-commit: ded0eb83449e8fcba22fd2736826336e101ffbcb
-- 
git-series 0.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-hwmon" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 3/4] pmbus (core): Add virtual page config bit

2017-11-19 Thread Andrew Jeffery
On Sun, 2017-11-19 at 08:49 -0800, Guenter Roeck wrote:
> On 11/17/2017 07:26 PM, Andrew Jeffery wrote:
> > Some circumstances call for virtual pages, to expose multiple values
> > packed into an extended PMBus register in a manner non-compliant with
> > the PMBus standard. An example of this is the Maxim MAX31785 controller, 
> > which
> > extends the READ_FAN_SPEED_1 PMBus register from two to four bytes to 
> > support
> > tach readings for both rotors of a dual rotor fan. This extended register
> > contains two word-sized values, one reporting the rate of the fastest rotor,
> > the other the rate of the slowest. The concept of virtual pages aids this
> > situation by mapping the page number onto the value to be selected from the
> > vectored result.
> > 
> > We should not try to set virtual pages on the device as such a page 
> > explicitly
> > doesn't exist; add a flag so we can avoid doing so.
> > 
> > Signed-off-by: Andrew Jeffery 
> > ---
> >   drivers/hwmon/pmbus/pmbus.h  |  2 ++
> >   drivers/hwmon/pmbus/pmbus_core.c | 10 +++---
> >   2 files changed, 9 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h
> > index b54d7604d3ef..d39d506aa63e 100644
> > --- a/drivers/hwmon/pmbus/pmbus.h
> > +++ b/drivers/hwmon/pmbus/pmbus.h
> > @@ -372,6 +372,8 @@ enum pmbus_sensor_classes {
> >   #define PMBUS_HAVE_PWM12  BIT(20)
> >   #define PMBUS_HAVE_PWM34  BIT(21)
> >   
> > +#define PMBUS_PAGE_VIRTUAL BIT(31)
> > +
> >   enum pmbus_data_format { linear = 0, direct, vid };
> >   enum vrm_version { vr11 = 0, vr12, vr13 };
> >   
> > diff --git a/drivers/hwmon/pmbus/pmbus_core.c 
> > b/drivers/hwmon/pmbus/pmbus_core.c
> > index 631db88526b6..ba97230fcde7 100644
> > --- a/drivers/hwmon/pmbus/pmbus_core.c
> > +++ b/drivers/hwmon/pmbus/pmbus_core.c
> > @@ -164,14 +164,18 @@ int pmbus_set_page(struct i2c_client *client, int 
> > page)
> > int rv = 0;
> > int newpage;
> >   
> > -   if (page >= 0 && page != data->currpage) {
> > +   if (page < 0 || page == data->currpage)
> > +   return 0;
> > +
> > +   if (!(data->info->func[page] & PMBUS_PAGE_VIRTUAL)) {
> > rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
> > newpage = i2c_smbus_read_byte_data(client, PMBUS_PAGE);
> > if (newpage != page)
> > rv = -EIO;
> 
> This should probably be something like
>   rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
>   if (rv < 0)
>   return rv;
>   newpage = i2c_smbus_read_byte_data(client, PMBUS_PAGE);
>   if (newpage < 0)
>   return newpage;
>   if (newpage != page)
>   return -EIO;
> 
> We can actually drop 'newpage' and just use 'rv'.
> 
> > -   else
> > -   data->currpage = page;
> > }
> > +
> > +   data->currpage = page;
> > +
> 
> ... otherwise currpage is set even on error.

Thanks for catching that, clearly I needed to pay more attention
resolving the conflicts when rebasing on hwmon-next. I'll address all
your points.

Cheers,

Andrew

> 
> > return rv;
> 
> this can then be
>   return 0;
> 
> >   }
> >   EXPORT_SYMBOL_GPL(pmbus_set_page);
> > 
> 
> 

signature.asc
Description: This is a digitally signed message part


Re: [PATCH] hwmon: Drop unnecessary 'default n' from Kconfig

2017-11-19 Thread Jean Delvare
Hi Guenter,

On Sun, 19 Nov 2017 09:16:02 -0800, Guenter Roeck wrote:
> 'default n' is default, so there is no need to specify it explicitly.
> 
> Signed-off-by: Guenter Roeck 
> ---
>  drivers/hwmon/Kconfig | 16 
>  1 file changed, 16 deletions(-)
> (...)

Reviewed-by: Jean Delvare 

(and heartily approved - thanks for doing that)

-- 
Jean Delvare
SUSE L3 Support
--
To unsubscribe from this list: send the line "unsubscribe linux-hwmon" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] hwmon: Drop unnecessary 'default n' from Kconfig

2017-11-19 Thread Guenter Roeck
'default n' is default, so there is no need to specify it explicitly.

Signed-off-by: Guenter Roeck 
---
 drivers/hwmon/Kconfig | 16 
 1 file changed, 16 deletions(-)

diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 530ff7c9234c..ef23553ff5cb 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -26,11 +26,9 @@ if HWMON
 
 config HWMON_VID
tristate
-   default n
 
 config HWMON_DEBUG_CHIP
bool "Hardware Monitoring Chip debugging messages"
-   default n
help
  Say Y here if you want the I2C chip drivers to produce a bunch of
  debug messages to the system log.  Select this if you are having
@@ -42,7 +40,6 @@ comment "Native drivers"
 config SENSORS_AB8500
tristate "AB8500 thermal monitoring"
depends on AB8500_GPADC && AB8500_BM
-   default n
help
  If you say yes here you get support for the thermal sensor part
  of the AB8500 chip. The driver includes thermal management for
@@ -302,7 +299,6 @@ config SENSORS_APPLESMC
select NEW_LEDS
select LEDS_CLASS
select INPUT_POLLDEV
-   default n
help
  This driver provides support for the Apple System Management
  Controller, which provides an accelerometer (Apple Sudden Motion
@@ -678,7 +674,6 @@ config SENSORS_JC42
 config SENSORS_POWR1220
tristate "Lattice POWR1220 Power Monitoring"
depends on I2C
-   default n
help
  If you say yes here you get access to the hardware monitoring
  functions of the Lattice POWR1220 isp Power Supply Monitoring,
@@ -702,7 +697,6 @@ config SENSORS_LTC2945
tristate "Linear Technology LTC2945"
depends on I2C
select REGMAP_I2C
-   default n
help
  If you say yes here you get support for Linear Technology LTC2945
  I2C System Monitor.
@@ -727,7 +721,6 @@ config SENSORS_LTC2990
 config SENSORS_LTC4151
tristate "Linear Technology LTC4151"
depends on I2C
-   default n
help
  If you say yes here you get support for Linear Technology LTC4151
  High Voltage I2C Current and Voltage Monitor interface.
@@ -738,7 +731,6 @@ config SENSORS_LTC4151
 config SENSORS_LTC4215
tristate "Linear Technology LTC4215"
depends on I2C
-   default n
help
  If you say yes here you get support for Linear Technology LTC4215
  Hot Swap Controller I2C interface.
@@ -750,7 +742,6 @@ config SENSORS_LTC4222
tristate "Linear Technology LTC4222"
depends on I2C
select REGMAP_I2C
-   default n
help
  If you say yes here you get support for Linear Technology LTC4222
  Dual Hot Swap Controller I2C interface.
@@ -761,7 +752,6 @@ config SENSORS_LTC4222
 config SENSORS_LTC4245
tristate "Linear Technology LTC4245"
depends on I2C
-   default n
help
  If you say yes here you get support for Linear Technology LTC4245
  Multiple Supply Hot Swap Controller I2C interface.
@@ -773,7 +763,6 @@ config SENSORS_LTC4260
tristate "Linear Technology LTC4260"
depends on I2C
select REGMAP_I2C
-   default n
help
  If you say yes here you get support for Linear Technology LTC4260
  Positive Voltage Hot Swap Controller I2C interface.
@@ -784,7 +773,6 @@ config SENSORS_LTC4260
 config SENSORS_LTC4261
tristate "Linear Technology LTC4261"
depends on I2C
-   default n
help
  If you say yes here you get support for Linear Technology LTC4261
  Negative Voltage Hot Swap Controller I2C interface.
@@ -1276,7 +1264,6 @@ config SENSORS_NSA320
 config SENSORS_PCF8591
tristate "Philips PCF8591 ADC/DAC"
depends on I2C
-   default n
help
  If you say yes here you get support for Philips PCF8591 4-channel
  ADC, 1-channel DAC chips.
@@ -1459,7 +1446,6 @@ config SENSORS_SMSC47B397
 
 config SENSORS_SCH56XX_COMMON
tristate
-   default n
 
 config SENSORS_SCH5627
tristate "SMSC SCH5627"
@@ -1505,7 +1491,6 @@ config SENSORS_STTS751
 config SENSORS_SMM665
tristate "Summit Microelectronics SMM665"
depends on I2C
-   default n
help
  If you say yes here you get support for the hardware monitoring
  features of the Summit Microelectronics SMM665/SMM665B Six-Channel
@@ -1792,7 +1777,6 @@ config SENSORS_W83795
 config SENSORS_W83795_FANCTRL
bool "Include automatic fan control support (DANGEROUS)"
depends on SENSORS_W83795
-   default n
help
  If you say yes here, support for automatic fan speed control
  will be included in the driver.
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-hwmon" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  

Re: [PATCH v5 3/4] pmbus (core): Add virtual page config bit

2017-11-19 Thread Guenter Roeck

On 11/17/2017 07:26 PM, Andrew Jeffery wrote:

Some circumstances call for virtual pages, to expose multiple values
packed into an extended PMBus register in a manner non-compliant with
the PMBus standard. An example of this is the Maxim MAX31785 controller, which
extends the READ_FAN_SPEED_1 PMBus register from two to four bytes to support
tach readings for both rotors of a dual rotor fan. This extended register
contains two word-sized values, one reporting the rate of the fastest rotor,
the other the rate of the slowest. The concept of virtual pages aids this
situation by mapping the page number onto the value to be selected from the
vectored result.

We should not try to set virtual pages on the device as such a page explicitly
doesn't exist; add a flag so we can avoid doing so.

Signed-off-by: Andrew Jeffery 
---
  drivers/hwmon/pmbus/pmbus.h  |  2 ++
  drivers/hwmon/pmbus/pmbus_core.c | 10 +++---
  2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h
index b54d7604d3ef..d39d506aa63e 100644
--- a/drivers/hwmon/pmbus/pmbus.h
+++ b/drivers/hwmon/pmbus/pmbus.h
@@ -372,6 +372,8 @@ enum pmbus_sensor_classes {
  #define PMBUS_HAVE_PWM12  BIT(20)
  #define PMBUS_HAVE_PWM34  BIT(21)
  
+#define PMBUS_PAGE_VIRTUAL	BIT(31)

+
  enum pmbus_data_format { linear = 0, direct, vid };
  enum vrm_version { vr11 = 0, vr12, vr13 };
  
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c

index 631db88526b6..ba97230fcde7 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -164,14 +164,18 @@ int pmbus_set_page(struct i2c_client *client, int page)
int rv = 0;
int newpage;
  
-	if (page >= 0 && page != data->currpage) {

+   if (page < 0 || page == data->currpage)
+   return 0;
+
+   if (!(data->info->func[page] & PMBUS_PAGE_VIRTUAL)) {
rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
newpage = i2c_smbus_read_byte_data(client, PMBUS_PAGE);
if (newpage != page)
rv = -EIO;


This should probably be something like
rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
if (rv < 0)
return rv;
newpage = i2c_smbus_read_byte_data(client, PMBUS_PAGE);
if (newpage < 0)
return newpage;
if (newpage != page)
return -EIO;

We can actually drop 'newpage' and just use 'rv'.


-   else
-   data->currpage = page;
}
+
+   data->currpage = page;
+


... otherwise currpage is set even on error.


return rv;


this can then be
return 0;


  }
  EXPORT_SYMBOL_GPL(pmbus_set_page);



--
To unsubscribe from this list: send the line "unsubscribe linux-hwmon" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html