Re: PWM control in NZXT Grid+ V3 and Smart Device

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

 



On Wed, Apr 21, 2021 at 01:48:03PM -0300, Jonas Malaco wrote:
> On Tue, Apr 13, 2021 at 09:45:29AM -0300, Jonas Malaco wrote:
> > Guenter (and others on this list),
> 
> Very gentle ping.
> 
> I also thought posting these questions first would be less disruptive
> than a RFC patch, but please let me know if you prefer the latter.
> 

It is a difficult subject, and I am struggling myself with the situations
you are presenting.

> Thanks again,
> Jonas
> 
> > 
> > I am getting ready to submit a driver for NZXT Grid+ V3 and Smart Device
> > (V1) fan controllers, but I am having trouble deciding how to expose
> > their PWM control due to some device limitations.
> > 
> > Before getting into those, let me first give some very basic context...
> > 
> > These devices are USB HIDs, and asynchronously send "status" reports
> > every 200 ms to communicate speed, current, voltage and control mode for
> > their channels (one channel per report).
> > 
> > Fans can be controlled by sending HID output reports to the device, and
> > both DC and PWM modes are supported.  The device features a special
> > initialization routine (that must be requested during probe) which
> > automatically detects the appropriate control mode for each channel.
> > 
> > Back to the device limitations...
> > 
> > The first is that PWM values can be set, but not read back.  And neither
> > hwmon[1] nor lm-sensors' pwmconfig/fancontrol expect pmw* attributes to
> > be WO.  One solution is to have the driver track the PWM values that are
> > set through it and return those, but is this acceptable?

I have seen a couple of those recently. I think returning -ENODATA
if the value isn't known (yet) is the best possible solution. I thought
about adding that to the ABI, actually.

> > 
> > The other starts with PWM control being disabled for channels that the
> > device identifies as unconnected.  This is not in itself a problem, but
> > the initialization routine (where the detection happens) is
> > asynchronous, takes somewhere around 5 seconds, and we do not have any
> > way of directly querying its result.  We only know the control mode of
> > each channel (be it DC, PWM or disabled) from the regular status
> > reports.

Again, I think the best solution is to return -ENODATA until the value
is known.

> > 
> > These limitations make it complicated to simply use is_visible() to hide
> > pwm attributes of unconnected channels.  We would need to register with
> > the hwmon subsystem only after getting enough post-initialization status
> > reports for all channels, and this would essentially mean to sleep for
> > 6+ seconds.  We would also need to unregister and re-register when going
> > through a suspend-reset_resume cycle, because the device may have its
> > state wiped, requiring reinitialization.[2]
> > 
I think the above should resolve that.

> > A different approach to handle this, which I have preferred _so far,_ is
> > to use pwm*_enable = 0 to report the unconnected channels to user-space,
> > while keeping the other pwm attributes visible.  But this comes with
> > other problems.
> > 
> > First, lm-sensors' pwmconfig expects to be able to write to a
> > pwm*_enable attribute if it exists, but the device does not support that
> > operation.  The hwmon documentation states that RW values may be RO, but
> > pwmconfig is out there and in use.  So far I simply return 0 to attempts
> > at those writes, silently ignoring them; functional, but certainly a
> > hack.

It is a bad idea to return 0 if the value is not accepted. You could check
if the written value matches the current value and return 0 if it does,
and an error such as -EOPNOTSUPP or -EINVAL otherwise.

> > 
> > Second, if PWM control is disabled for a channel, but its pwm* and
> > pwm*_mode attributes are still visible, what should we return when
> > user-space attempts to write to them?  The practical answer may simply
> > be to return -EOPNOTSUPP, but this makes me wonder if the whole approach
> > (of handling these cases with pwm*_enable instead of is_visible()) is
> > not doomed.
> > 
Mode isn't really writeable either, isn't it ? If so, use the same trick as
with the _enable attribute.

The same is effectively true for the pwm value itself: Since both _enable
and _mode are effectively read-only, you can accept a write only if
fan control is enabled, and return an error if it isn't.

> > A final minor problem is that channels detected as unconnected run at
> > 40% PWM, but the documentation for pwm*_enable == 0 is a bit too
> > specific: "no fan speed control (i.e. fan at *full* speed)" (emphasis
> > mine).

Just document the difference. Reality doesn't always match our expectations.

Thanks,
Guenter

> > 
> > Do you have any suggestions and/or recommendations?
> > 
> > If it helps, a pre-RFC (but functional and mostly clean) version of the
> > driver can be found at:
> > 
> > https://github.com/jonasmalacofilho/linux/blob/p-hwmon-add-nzxt-smartdevice-gridplus3/drivers/hwmon/nzxt-smartdevice.c
> > 
> > Thanks,
> > Jonas
> > 
> > [1] According to Documentation/hwmon/sysfs-interface.rst.
> > [2] The device also does not respond to HID Get_Report, so it is not
> >     trivial to check whether it really needs to be reinitialized, since
> >     the only symptom of that being necessary is the absence of the
> >     asynchronous status reports.



[Index of Archives]     [LM Sensors]     [Linux Sound]     [ALSA Users]     [ALSA Devel]     [Linux Audio Users]     [Linux Media]     [Kernel]     [Gimp]     [Yosemite News]     [Linux Media]

  Powered by Linux