w83l786ng driver bug, questions, and 1st round patch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Below is a description of two problems, some questions about how best
to resolve them, a transcript showing the behaviour, a minimal patch that
fixes just the first problem, and a transcript showing the improved
behaviour.

Problem #1:
There is a bug preventing setting the mode of the w83l786ng fan control.
sysfs will forever report mode 1.
The driver can do a one-way set of the hardware to mode 2, even though
that will never be reflected in sysfs.
It is then impossible to set hardware back to mode 1 via the driver.

Problem #2:
The "enable" and "mode" sysfs files are hooked up to the bitfields backward.
Do we want to fix this?
I'd worry about backward-compatibility, except that the current driver does
not
work with fan-control outside of mode 1, so perhaps there are no users of
the
advanced modes or PWM/DC switch, and thus no backward-compatibility
to break?  Although some people may have figured out the reversal, and
count on
setting pwmX_mode -> 0 to turn off PWM enable and drive the fan in DC mode?

While I'm submitting a patch to fix #1 and perhaps next for #2, are there
any
other updates or conventions to follow to normalize this driver against the
rest?
Perhaps:
  a) make the mode 0-based (0,1,2,3) instead of (1,2,forbidden,forbidden)
  b) make the mode named? (manual, cruise, smart, set)
  c) have the fan control naming convention not tied to 'pwm'
     (the chip supports pwm and DC modes.  I'm actually using it in DC mode)

In my own source tree, I've got a quick'n'dirty version exposing the duty
cycles and temp limits for thermal cruise and smart fan modes, permitting
modes 3 and 4, and supporting configurable voltage scaling.

Let me know your thoughts on problems #1 and #2 and naming conventions.
If the additional modes and functionality are desired, I can clean that up
and submit it, once the first round of questions and conventions are
settled.

Transcript:

# The original author is using pwmX_enable to control the FANx_MODE
#  fields, in bits 2-3, and 4-5 of register 0x80
# And is using pwmX_mode to control the EN_PWMx fields, in
#  bits 6, and 7.
# The naming is backwards, but there is also a bug after coping
#  with the reversal.
# Consider the following:

$ cat pwm1_enable pwm2_enable
1
1
$ i2cget -f -y 0 0x2e 0x80
0x00

# Everything is consistent so far.  The original author's comments in the
# code state that he allows the first two 'modes' in pwmX_enable, 1 and 2.
# His sysfs reflection of them are 1-based, so:
# bits 2-3 = 0b00 -> pwm1_enable = 0 (+1) = 1
# bits 4-5 = 0b00 -> pwm2_enable = 0 (+1) = 1
# and he is intentionally restricting us from modes 3 and 4.  Now:

$ echo 1 > pwm1_enable
$ cat pwm1_enable pwm2_enable
1
1
$ i2cget -f -y 0 0x2e 0x80
0x00

# Everything's still OK.  He's mapping his 1-based mode into the
# register correctly.  But now:

$ echo 2 > pwm1_enable
$ cat pwm1_enable pwm2_enable
1
1
$ i2cget -f -y 0 0x2e 0x80
0x04

# The bit got set - hardware is now in "mode 2" (thermal cruise)
# But the sysfs file still says we're in mode 1
# Let's try to go back:

$ echo 1 > pwm1_enable
$ cat pwm1_enable pwm2_enable
1
1
$ i2cget -f -y 0 0x2e 0x80
0x04

# Nope, we're now forever stuck in mode 2 on the hardware, but
# sysfs will forever say we're in mode 1.

# Note the power up default is actually mode 4, which is even more
# confusing (sysfs would tell you we're in mode 3, until you first
# touch the mode, then it would lock back into mode 1 behavior.
# For the above I made things less confusing for the reader by
# first forcing mode 1.)

A copy of the datasheet can be found at:

http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/CloudAndComputingIC/HardwareMonitor/HWMonitorforGraphicCardNBAndIA/Documents/W83L786NG_W83L786NR.pdf

The pertinent section is:
   8.23 Fan Control Register - Index 80h, on page 30.

Possibly related mailing list reference to w83l786ng problems:
  http://marc.info/?l=lm-sensors&m=136974114501850

Patch addressing just problem #1:
--- a/w83l786ng.c
+++ b/w83l786ng.c
@@ -523,7 +523,7 @@ store_pwm_enable(struct device *dev, struct
device_attribute *attr,
        mutex_lock(&data->update_lock);
        reg = w83l786ng_read_value(client, W83L786NG_REG_FAN_CFG);
        data->pwm_enable[nr] = val;
-       reg &= ~(0x02 << W83L786NG_PWM_ENABLE_SHIFT[nr]);
+       reg &= ~(0x03 << W83L786NG_PWM_ENABLE_SHIFT[nr]);
        reg |= (val - 1) << W83L786NG_PWM_ENABLE_SHIFT[nr];
        w83l786ng_write_value(client, W83L786NG_REG_FAN_CFG, reg);
        mutex_unlock(&data->update_lock);
@@ -790,7 +790,7 @@ static struct w83l786ng_data
*w83l786ng_update_device(struct device *dev)
                            ((pwmcfg >> W83L786NG_PWM_MODE_SHIFT[i]) & 1)
                            ? 0 : 1;
                        data->pwm_enable[i] =
-                           ((pwmcfg >> W83L786NG_PWM_ENABLE_SHIFT[i]) & 2)
+ 1;
+                           ((pwmcfg >> W83L786NG_PWM_ENABLE_SHIFT[i]) & 3)
+ 1;
                        data->pwm[i] = w83l786ng_read_value(client,
                            W83L786NG_REG_PWM[i]);
                }
-----PATCH END-----

In short:
chunk 1 used to clear just bit 2 (so no modes 3 or 4), then always OR in
bit 1.
  Once set, no going back!  Now we clear both bits, and then OR in the mode.
chunk 2 used to always request bit 2 (which this driver always set to zero),
  and add one.  Thus you always appeared to be in "mode 1", unless the
hardware
  was in mode 3 or 4 by means other than the driver, then you would
  appear to be in mode 3...
  Now the driver will correctly report the mode (1, 2, 3, or 4).

Transcript after loading patched module:

$ sudo rmmod w83l786ng
$ sudo insmod ./w83l786ng.ko
$ cat pwm1_enable pwm2_enable
1
1
$ i2cget -f -y 0 0x2e 0x80
0x00
$ echo 1 > pwm1_enable
$ cat pwm1_enable pwm2_enable
1
1
$ i2cget -f -y 0 0x2e 0x80
0x00
$ echo 2 > pwm1_enable
$ cat pwm1_enable pwm2_enable
2
1
$ i2cget -f -y 0 0x2e 0x80
0x04
$ echo 1 > pwm1_enable
$ cat pwm1_enable pwm2_enable
1
1
$ i2cget -f -y 0 0x2e 0x80
0x00

Which is the expected behaviour.

Regards,

  Brian
_______________________________________________
lm-sensors mailing list
lm-sensors@xxxxxxxxxxxxxx
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors




[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux