Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Input: max8997_haptic - optimize PWM configuration

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>

authored by

Uwe Kleine-König and committed by
Dmitry Torokhov
54e626d0 fc75e51e

+48 -50
+48 -50
drivers/input/misc/max8997_haptic.c
··· 53 53 unsigned int pattern_signal_period; 54 54 }; 55 55 56 - static int max8997_haptic_set_duty_cycle(struct max8997_haptic *chip) 56 + static void max8997_haptic_set_internal_duty_cycle(struct max8997_haptic *chip) 57 57 { 58 - int ret = 0; 58 + u8 duty_index = DIV_ROUND_UP(chip->level * 64, 100); 59 59 60 - if (chip->mode == MAX8997_EXTERNAL_MODE) { 61 - unsigned int duty = chip->pwm_period * chip->level / 100; 62 - ret = pwm_config(chip->pwm, duty, chip->pwm_period); 63 - } else { 64 - u8 duty_index = 0; 65 - 66 - duty_index = DIV_ROUND_UP(chip->level * 64, 100); 67 - 68 - switch (chip->internal_mode_pattern) { 69 - case 0: 70 - max8997_write_reg(chip->client, 71 - MAX8997_HAPTIC_REG_SIGPWMDC1, duty_index); 72 - break; 73 - case 1: 74 - max8997_write_reg(chip->client, 75 - MAX8997_HAPTIC_REG_SIGPWMDC2, duty_index); 76 - break; 77 - case 2: 78 - max8997_write_reg(chip->client, 79 - MAX8997_HAPTIC_REG_SIGPWMDC3, duty_index); 80 - break; 81 - case 3: 82 - max8997_write_reg(chip->client, 83 - MAX8997_HAPTIC_REG_SIGPWMDC4, duty_index); 84 - break; 85 - default: 86 - break; 87 - } 60 + switch (chip->internal_mode_pattern) { 61 + case 0: 62 + max8997_write_reg(chip->client, 63 + MAX8997_HAPTIC_REG_SIGPWMDC1, duty_index); 64 + break; 65 + case 1: 66 + max8997_write_reg(chip->client, 67 + MAX8997_HAPTIC_REG_SIGPWMDC2, duty_index); 68 + break; 69 + case 2: 70 + max8997_write_reg(chip->client, 71 + MAX8997_HAPTIC_REG_SIGPWMDC3, duty_index); 72 + break; 73 + case 3: 74 + max8997_write_reg(chip->client, 75 + MAX8997_HAPTIC_REG_SIGPWMDC4, duty_index); 76 + break; 77 + default: 78 + break; 88 79 } 89 - return ret; 90 80 } 91 81 92 82 static void max8997_haptic_configure(struct max8997_haptic *chip) ··· 145 155 146 156 guard(mutex)(&chip->mutex); 147 157 148 - error = max8997_haptic_set_duty_cycle(chip); 149 - if (error) { 150 - dev_err(chip->dev, "set_pwm_cycle failed, error: %d\n", error); 151 - return; 152 - } 158 + if (chip->mode != MAX8997_EXTERNAL_MODE) 159 + max8997_haptic_set_internal_duty_cycle(chip); 153 160 154 161 if (!chip->enabled) { 155 162 error = regulator_enable(chip->regulator); ··· 155 168 return; 156 169 } 157 170 max8997_haptic_configure(chip); 158 - if (chip->mode == MAX8997_EXTERNAL_MODE) { 159 - error = pwm_enable(chip->pwm); 160 - if (error) { 161 - dev_err(chip->dev, "Failed to enable PWM\n"); 162 - regulator_disable(chip->regulator); 163 - return; 164 - } 165 - } 166 - chip->enabled = true; 167 171 } 172 + 173 + /* 174 + * It would be more straight forward to configure the external PWM 175 + * earlier i.e. when the internal duty_cycle is setup in internal mode. 176 + * But historically this is done only after the regulator was enabled 177 + * and max8997_haptic_configure() set the enable bit in 178 + * MAX8997_HAPTIC_REG_CONF2. So better keep it this way. 179 + */ 180 + if (chip->mode == MAX8997_EXTERNAL_MODE) { 181 + struct pwm_state state; 182 + 183 + pwm_init_state(chip->pwm, &state); 184 + state.period = chip->pwm_period; 185 + state.duty_cycle = chip->pwm_period * chip->level / 100; 186 + state.enabled = true; 187 + 188 + error = pwm_apply_might_sleep(chip->pwm, &state); 189 + if (error) { 190 + dev_err(chip->dev, "Failed to enable PWM\n"); 191 + regulator_disable(chip->regulator); 192 + return; 193 + } 194 + } 195 + 196 + chip->enabled = true; 168 197 } 169 198 170 199 static void max8997_haptic_disable(struct max8997_haptic *chip) ··· 285 282 goto err_free_mem; 286 283 } 287 284 288 - /* 289 - * FIXME: pwm_apply_args() should be removed when switching to 290 - * the atomic PWM API. 291 - */ 292 - pwm_apply_args(chip->pwm); 293 285 break; 294 286 295 287 default: