pwm: core: Support new usage_power setting in PWM state
authorClemens Gruber <clemens.gruber@pqgruber.com>
Fri, 7 May 2021 13:18:42 +0000 (15:18 +0200)
committerThierry Reding <thierry.reding@gmail.com>
Fri, 4 Jun 2021 09:43:52 +0000 (11:43 +0200)
If usage_power is set, the PWM driver is only required to maintain
the power output but has more freedom regarding signal form.

If supported, the signal can be optimized, for example to
improve EMI by phase shifting individual channels.

Signed-off-by: Clemens Gruber <clemens.gruber@pqgruber.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Documentation/driver-api/pwm.rst
drivers/pwm/core.c
include/linux/pwm.h

index a7ca4f58305a8e27e9131b0b9fdc476443037f4e..750734a7f874aedb6c5e204b6a74bc4028fe4693 100644 (file)
@@ -48,6 +48,10 @@ After being requested, a PWM has to be configured using::
 
 This API controls both the PWM period/duty_cycle config and the
 enable/disable state.
+There is also a usage_power setting: If set, the PWM driver is only required to
+maintain the power output but has more freedom regarding signal form.
+If supported by the driver, the signal can be optimized, for example to improve
+EMI by phase shifting the individual channels of a chip.
 
 The pwm_config(), pwm_enable() and pwm_disable() functions are just wrappers
 around pwm_apply_state() and should not be used if the user wants to change
index c165c5822703e765e1346a15be576bd766a80c9b..a42999f877d25ab4eb83fc9063993b4c37048c2a 100644 (file)
@@ -536,7 +536,8 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state)
        if (state->period == pwm->state.period &&
            state->duty_cycle == pwm->state.duty_cycle &&
            state->polarity == pwm->state.polarity &&
-           state->enabled == pwm->state.enabled)
+           state->enabled == pwm->state.enabled &&
+           state->usage_power == pwm->state.usage_power)
                return 0;
 
        if (chip->ops->apply) {
@@ -1241,6 +1242,9 @@ static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
                seq_printf(s, " polarity: %s",
                           state.polarity ? "inverse" : "normal");
 
+               if (state.usage_power)
+                       seq_puts(s, " usage_power");
+
                seq_puts(s, "\n");
        }
 }
index 5bb90af4997e0ca895380ecf4d8829241438aea6..5a73251d28e3f4c441ef63e95f362f4a7c98325f 100644 (file)
@@ -54,12 +54,17 @@ enum {
  * @duty_cycle: PWM duty cycle (in nanoseconds)
  * @polarity: PWM polarity
  * @enabled: PWM enabled status
+ * @usage_power: If set, the PWM driver is only required to maintain the power
+ *               output but has more freedom regarding signal form.
+ *               If supported, the signal can be optimized, for example to
+ *               improve EMI by phase shifting individual channels.
  */
 struct pwm_state {
        u64 period;
        u64 duty_cycle;
        enum pwm_polarity polarity;
        bool enabled;
+       bool usage_power;
 };
 
 /**
@@ -188,6 +193,7 @@ static inline void pwm_init_state(const struct pwm_device *pwm,
        state->period = args.period;
        state->polarity = args.polarity;
        state->duty_cycle = 0;
+       state->usage_power = false;
 }
 
 /**
@@ -558,6 +564,7 @@ static inline void pwm_apply_args(struct pwm_device *pwm)
        state.enabled = false;
        state.polarity = pwm->args.polarity;
        state.period = pwm->args.period;
+       state.usage_power = false;
 
        pwm_apply_state(pwm, &state);
 }