]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Input: max8997_haptic - optimize PWM configuration
authorUwe Kleine-König <u.kleine-koenig@baylibre.com>
Mon, 30 Jun 2025 19:24:31 +0000 (12:24 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Mon, 30 Jun 2025 19:30:22 +0000 (12:30 -0700)
Both pwm_config() and pwm_enable() are wrappers around
pwm_apply_might_sleep(). Instead of calling this function twice only
call it once without an intermediate step.

Setup the PWM in max8997_haptic_enable() only where it was enabled
historically. max8997_haptic_set_duty_cycle() is renamed accordingly to
make it clear this function is only about the internal setup now.
pwm_config() was called earlier back then, but that call has no effect
on the hardware when the PWM is disabled, so delaying this configuration
doesn't make a difference.

As pwm_apply_might_sleep() is used now defining the whole state of the
PWM, the call to pwm_apply_args() in .probe() can be dropped now, too.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Link: https://lore.kernel.org/r/20250630093718.2062359-2-u.kleine-koenig@baylibre.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/misc/max8997_haptic.c

index f97f341ee0bb2ee0de0a66106a865b14845c6258..d5e051a25a746d9da35a151a419b511492abc2f7 100644 (file)
@@ -53,40 +53,30 @@ struct max8997_haptic {
        unsigned int pattern_signal_period;
 };
 
-static int max8997_haptic_set_duty_cycle(struct max8997_haptic *chip)
+static void max8997_haptic_set_internal_duty_cycle(struct max8997_haptic *chip)
 {
-       int ret = 0;
+       u8 duty_index = DIV_ROUND_UP(chip->level * 64, 100);
 
-       if (chip->mode == MAX8997_EXTERNAL_MODE) {
-               unsigned int duty = chip->pwm_period * chip->level / 100;
-               ret = pwm_config(chip->pwm, duty, chip->pwm_period);
-       } else {
-               u8 duty_index = 0;
-
-               duty_index = DIV_ROUND_UP(chip->level * 64, 100);
-
-               switch (chip->internal_mode_pattern) {
-               case 0:
-                       max8997_write_reg(chip->client,
-                               MAX8997_HAPTIC_REG_SIGPWMDC1, duty_index);
-                       break;
-               case 1:
-                       max8997_write_reg(chip->client,
-                               MAX8997_HAPTIC_REG_SIGPWMDC2, duty_index);
-                       break;
-               case 2:
-                       max8997_write_reg(chip->client,
-                               MAX8997_HAPTIC_REG_SIGPWMDC3, duty_index);
-                       break;
-               case 3:
-                       max8997_write_reg(chip->client,
-                               MAX8997_HAPTIC_REG_SIGPWMDC4, duty_index);
-                       break;
-               default:
-                       break;
-               }
+       switch (chip->internal_mode_pattern) {
+       case 0:
+               max8997_write_reg(chip->client,
+                                 MAX8997_HAPTIC_REG_SIGPWMDC1, duty_index);
+               break;
+       case 1:
+               max8997_write_reg(chip->client,
+                                 MAX8997_HAPTIC_REG_SIGPWMDC2, duty_index);
+               break;
+       case 2:
+               max8997_write_reg(chip->client,
+                                 MAX8997_HAPTIC_REG_SIGPWMDC3, duty_index);
+               break;
+       case 3:
+               max8997_write_reg(chip->client,
+                                 MAX8997_HAPTIC_REG_SIGPWMDC4, duty_index);
+               break;
+       default:
+               break;
        }
-       return ret;
 }
 
 static void max8997_haptic_configure(struct max8997_haptic *chip)
@@ -155,11 +145,8 @@ static void max8997_haptic_enable(struct max8997_haptic *chip)
 
        guard(mutex)(&chip->mutex);
 
-       error = max8997_haptic_set_duty_cycle(chip);
-       if (error) {
-               dev_err(chip->dev, "set_pwm_cycle failed, error: %d\n", error);
-               return;
-       }
+       if (chip->mode != MAX8997_EXTERNAL_MODE)
+               max8997_haptic_set_internal_duty_cycle(chip);
 
        if (!chip->enabled) {
                error = regulator_enable(chip->regulator);
@@ -168,16 +155,32 @@ static void max8997_haptic_enable(struct max8997_haptic *chip)
                        return;
                }
                max8997_haptic_configure(chip);
-               if (chip->mode == MAX8997_EXTERNAL_MODE) {
-                       error = pwm_enable(chip->pwm);
-                       if (error) {
-                               dev_err(chip->dev, "Failed to enable PWM\n");
-                               regulator_disable(chip->regulator);
-                               return;
-                       }
+       }
+
+       /*
+        * It would be more straight forward to configure the external PWM
+        * earlier i.e. when the internal duty_cycle is setup in internal mode.
+        * But historically this is done only after the regulator was enabled
+        * and max8997_haptic_configure() set the enable bit in
+        * MAX8997_HAPTIC_REG_CONF2. So better keep it this way.
+        */
+       if (chip->mode == MAX8997_EXTERNAL_MODE) {
+               struct pwm_state state;
+
+               pwm_init_state(chip->pwm, &state);
+               state.period = chip->pwm_period;
+               state.duty_cycle = chip->pwm_period * chip->level / 100;
+               state.enabled = true;
+
+               error = pwm_apply_might_sleep(chip->pwm, &state);
+               if (error) {
+                       dev_err(chip->dev, "Failed to enable PWM\n");
+                       regulator_disable(chip->regulator);
+                       return;
                }
-               chip->enabled = true;
        }
+
+       chip->enabled = true;
 }
 
 static void max8997_haptic_disable(struct max8997_haptic *chip)
@@ -282,11 +285,6 @@ static int max8997_haptic_probe(struct platform_device *pdev)
                        goto err_free_mem;
                }
 
-               /*
-                * FIXME: pwm_apply_args() should be removed when switching to
-                * the atomic PWM API.
-                */
-               pwm_apply_args(chip->pwm);
                break;
 
        default: