* [PATCH] arctic_fan_controller: Add a way to set a default value state on kernel bootup
@ 2026-09-11 15:36 marco.rodolfi
2026-09-11 21:46 ` Guenter Roeck
0 siblings, 1 reply; 2+ messages in thread
From: marco.rodolfi @ 2026-09-11 15:36 UTC (permalink / raw)
To: Linux Hwmon
This allows to quickly set the connected fan(s) speed on bootup to a
sensible value, rather than the randomly initialized values as the
default behavior was.
Signed-off-by: Marco Rodolfi <marco.rodolfi@tuta.io>
---
arctic_fan_controller.c | 34 ++++++++++++++++++++++++++++------
1 file changed, 28 insertions(+), 6 deletions(-)
diff --git a/drivers/hwmon/arctic_fan_controller.c b/drivers/hwmon/arctic_fan_controller.c
index 75cc78d..00ca803 100644
--- a/drivers/hwmon/arctic_fan_controller.c
+++ b/drivers/hwmon/arctic_fan_controller.c
@@ -17,6 +17,7 @@
#include <linux/jiffies.h>
#include <linux/minmax.h>
#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/unaligned.h>
@@ -36,6 +37,14 @@
*/
#define ARCTIC_ACK_TIMEOUT_MS 1000
+static int all_fan_default = 100;
+module_param(all_fan_default, int, 0);
+MODULE_PARM_DESC(all_fan_default, "This parameter controls the default value that the fan(s) will have once the module is loaded. The default is 100/255 (which correspond to 50%).");
+
+static int fanx_default[ARCTIC_NUM_FANS] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
+module_param_array(fanx_default, int, NULL, 0);
+MODULE_PARM_DESC(fanx_default, "This parameter controls the default value that each individual fan will have once the module is loaded. This parameter takes precedence over the global default. If you don't want to set a default speed for a specific fan, specify -1 in the array. The default is -1 for all fans in the array (so use the global default for all of them).");
+
struct arctic_fan_data {
struct hid_device *hdev;
struct device *hwmon_dev; /* stored for explicit unregister in remove() */
@@ -254,16 +263,20 @@ static int arctic_fan_reset_resume(struct hid_device *hdev)
{
struct arctic_fan_data *priv = hid_get_drvdata(hdev);
unsigned long flags;
+ int i;
/*
* The device resets its PWM channels to hardware defaults on power
- * loss during suspend. Clear the cached duty values so they reflect
- * the unknown hardware state, consistent with probe-time behaviour
- * (the device has no GET_REPORT support). Hold in_report_lock so
- * this does not race with a concurrent pwm read or write callback.
+ * loss during suspend. Set the requested default state again to
+ * reconfigure the hardware correctly. Hold in_report_lock so this
+ * does not race with a concurrent pwm read or write callback.
*/
spin_lock_irqsave(&priv->in_report_lock, flags);
- memset(priv->pwm_duty, 0, sizeof(priv->pwm_duty));
+ for (i = 0; i < ARCTIC_NUM_FANS; i++) {
+ int speed_selected = fanx_default[i] == -1 ? all_fan_default : fanx_default[i];
+
+ arctic_fan_write(&hdev->dev, hwmon_pwm, hwmon_pwm_input, i, speed_selected);
+ }
spin_unlock_irqrestore(&priv->in_report_lock, flags);
return 0;
}
@@ -272,7 +285,7 @@ static int arctic_fan_probe(struct hid_device *hdev,
const struct hid_device_id *id)
{
struct arctic_fan_data *priv;
- int ret;
+ int ret, i;
if (!hid_is_usb(hdev))
return -ENODEV;
@@ -317,6 +331,17 @@ static int arctic_fan_probe(struct hid_device *hdev,
priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, "arctic_fan",
priv, &arctic_fan_chip_info,
NULL);
+ /*
+ * Check which fan default value to use, chosen between the array of fan(s)
+ * values or the default fans value (first takes precedence) and write the
+ * corresponding value to the hardware.
+ */
+ for (i = 0; i < ARCTIC_NUM_FANS; i++) {
+ int speed_selected = fanx_default[i] == -1 ? all_fan_default : fanx_default[i];
+
+ arctic_fan_write(&hdev->dev, hwmon_pwm, hwmon_pwm_input, i, speed_selected);
+ }
+
if (IS_ERR(priv->hwmon_dev)) {
ret = PTR_ERR(priv->hwmon_dev);
goto out_close;
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] arctic_fan_controller: Add a way to set a default value state on kernel bootup
2026-09-11 15:36 [PATCH] arctic_fan_controller: Add a way to set a default value state on kernel bootup marco.rodolfi
@ 2026-09-11 21:46 ` Guenter Roeck
0 siblings, 0 replies; 2+ messages in thread
From: Guenter Roeck @ 2026-09-11 21:46 UTC (permalink / raw)
To: marco.rodolfi; +Cc: Linux Hwmon
On Fri, Sep 11, 2026 at 05:36:13PM +0200, marco.rodolfi@tuta.io wrote:
> This allows to quickly set the connected fan(s) speed on bootup to a
> sensible value, rather than the randomly initialized values as the
> default behavior was.
>
> Signed-off-by: Marco Rodolfi <marco.rodolfi@tuta.io>
This patch is corrupted. On top of that, it has various checkpatch issues
which could easily be discovered by running checkpatch. On top of that, it
conflicts with a patch that I just accepted, which sets the default speed
to 40%. I think that is sufficient.
Anything further should explore the possibility of caching the current
values prior to suspend and restoring it on resume. I do not see the need
for module parameters.
Thanks,
Guenter
> ---
> arctic_fan_controller.c | 34 ++++++++++++++++++++++++++++------
> 1 file changed, 28 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/hwmon/arctic_fan_controller.c b/drivers/hwmon/arctic_fan_controller.c
> index 75cc78d..00ca803 100644
> --- a/drivers/hwmon/arctic_fan_controller.c
> +++ b/drivers/hwmon/arctic_fan_controller.c
> @@ -17,6 +17,7 @@
> #include <linux/jiffies.h>
> #include <linux/minmax.h>
> #include <linux/module.h>
> +#include <linux/moduleparam.h>
> #include <linux/spinlock.h>
> #include <linux/string.h>
> #include <linux/unaligned.h>
> @@ -36,6 +37,14 @@
> */
> #define ARCTIC_ACK_TIMEOUT_MS 1000
>
> +static int all_fan_default = 100;
> +module_param(all_fan_default, int, 0);
> +MODULE_PARM_DESC(all_fan_default, "This parameter controls the default value that the fan(s) will have once the module is loaded. The default is 100/255 (which correspond to 50%).");
> +
> +static int fanx_default[ARCTIC_NUM_FANS] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
> +module_param_array(fanx_default, int, NULL, 0);
> +MODULE_PARM_DESC(fanx_default, "This parameter controls the default value that each individual fan will have once the module is loaded. This parameter takes precedence over the global default. If you don't want to set a default speed for a specific fan, specify -1 in the array. The default is -1 for all fans in the array (so use the global default for all of them).");
> +
> struct arctic_fan_data {
> struct hid_device *hdev;
> struct device *hwmon_dev; /* stored for explicit unregister in remove() */
> @@ -254,16 +263,20 @@ static int arctic_fan_reset_resume(struct hid_device *hdev)
> {
> struct arctic_fan_data *priv = hid_get_drvdata(hdev);
> unsigned long flags;
> + int i;
>
> /*
> * The device resets its PWM channels to hardware defaults on power
> - * loss during suspend. Clear the cached duty values so they reflect
> - * the unknown hardware state, consistent with probe-time behaviour
> - * (the device has no GET_REPORT support). Hold in_report_lock so
> - * this does not race with a concurrent pwm read or write callback.
> + * loss during suspend. Set the requested default state again to
> + * reconfigure the hardware correctly. Hold in_report_lock so this
> + * does not race with a concurrent pwm read or write callback.
> */
> spin_lock_irqsave(&priv->in_report_lock, flags);
> - memset(priv->pwm_duty, 0, sizeof(priv->pwm_duty));
> + for (i = 0; i < ARCTIC_NUM_FANS; i++) {
> + int speed_selected = fanx_default[i] == -1 ? all_fan_default : fanx_default[i];
> +
> + arctic_fan_write(&hdev->dev, hwmon_pwm, hwmon_pwm_input, i, speed_selected);
> + }
> spin_unlock_irqrestore(&priv->in_report_lock, flags);
> return 0;
> }
> @@ -272,7 +285,7 @@ static int arctic_fan_probe(struct hid_device *hdev,
> const struct hid_device_id *id)
> {
> struct arctic_fan_data *priv;
> - int ret;
> + int ret, i;
>
> if (!hid_is_usb(hdev))
> return -ENODEV;
> @@ -317,6 +331,17 @@ static int arctic_fan_probe(struct hid_device *hdev,
> priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, "arctic_fan",
> priv, &arctic_fan_chip_info,
> NULL);
> + /*
> + * Check which fan default value to use, chosen between the array of fan(s)
> + * values or the default fans value (first takes precedence) and write the
> + * corresponding value to the hardware.
> + */
> + for (i = 0; i < ARCTIC_NUM_FANS; i++) {
> + int speed_selected = fanx_default[i] == -1 ? all_fan_default : fanx_default[i];
> +
> + arctic_fan_write(&hdev->dev, hwmon_pwm, hwmon_pwm_input, i, speed_selected);
> + }
> +
> if (IS_ERR(priv->hwmon_dev)) {
> ret = PTR_ERR(priv->hwmon_dev);
> goto out_close;
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-11 21:46 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-11 15:36 [PATCH] arctic_fan_controller: Add a way to set a default value state on kernel bootup marco.rodolfi
2026-09-11 21:46 ` Guenter Roeck
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox