mirror of
https://github.com/VIKINGYFY/immortalwrt.git
synced 2025-12-16 17:15:26 +00:00
60 lines
3.0 KiB
Diff
60 lines
3.0 KiB
Diff
From d041b76ac9fb9e60e7cdb0265ed9d8b6058a88bf Mon Sep 17 00:00:00 2001
|
||
From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@baylibre.com>
|
||
Date: Wed, 30 Apr 2025 13:56:00 +0200
|
||
Subject: [PATCH] pwm: Formally describe the procedure used to pick a hardware
|
||
waveform setting
|
||
MIME-Version: 1.0
|
||
Content-Type: text/plain; charset=UTF-8
|
||
Content-Transfer-Encoding: 8bit
|
||
|
||
This serves as specification for both, PWM consumers and the respective
|
||
callback for lowlevel drivers.
|
||
|
||
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
|
||
Link: https://lore.kernel.org/r/d2916bfa70274961ded26b07ab6998c36b90e69a.1746010245.git.u.kleine-koenig@baylibre.com
|
||
Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>
|
||
---
|
||
drivers/pwm/core.c | 24 +++++++++++++++++++++++-
|
||
1 file changed, 23 insertions(+), 1 deletion(-)
|
||
|
||
--- a/drivers/pwm/core.c
|
||
+++ b/drivers/pwm/core.c
|
||
@@ -231,7 +231,9 @@ static int __pwm_write_waveform(struct p
|
||
*
|
||
* Usually all values passed in @wf are rounded down to the nearest possible
|
||
* value (in the order period_length_ns, duty_length_ns and then
|
||
- * duty_offset_ns). Only if this isn't possible, a value might grow.
|
||
+ * duty_offset_ns). Only if this isn't possible, a value might grow. See the
|
||
+ * documentation for pwm_set_waveform_might_sleep() for a more formal
|
||
+ * description.
|
||
*
|
||
* Returns: 0 on success, 1 if at least one value had to be rounded up or a
|
||
* negative errno.
|
||
@@ -411,6 +413,26 @@ static int __pwm_set_waveform(struct pwm
|
||
* possible/needed. In the above example requesting .period_length_ns = 94 and
|
||
* @exact = true, you get the hardware configured with period = 93.5 ns.
|
||
*
|
||
+ * Let C be the set of possible hardware configurations for a given PWM device,
|
||
+ * consisting of tuples (p, d, o) where p is the period length, d is the duty
|
||
+ * length and o the duty offset.
|
||
+ *
|
||
+ * The following algorithm is implemented to pick the hardware setting
|
||
+ * (p, d, o) ∈ C for a given request (p', d', o') with @exact = false::
|
||
+ *
|
||
+ * p = max( { ṗ | ∃ ḋ, ȯ : (ṗ, ḋ, ȯ) ∈ C ∧ ṗ ≤ p' } ∪ { min({ ṗ | ∃ ḋ, ȯ : (ṗ, ḋ, ȯ) ∈ C }) })
|
||
+ * d = max( { ḋ | ∃ ȯ : (p, ḋ, ȯ) ∈ C ∧ ḋ ≤ d' } ∪ { min({ ḋ | ∃ ȯ : (p, ḋ, ȯ) ∈ C }) })
|
||
+ * o = max( { ȯ | (p, d, ȯ) ∈ C ∧ ȯ ≤ o' } ∪ { min({ ȯ | (p, d, ȯ) ∈ C }) })
|
||
+ *
|
||
+ * In words: The chosen period length is the maximal possible period length not
|
||
+ * bigger than the requested period length and if that doesn't exist, the
|
||
+ * minimal period length. The chosen duty length is the maximal possible duty
|
||
+ * length that is compatible with the chosen period length and isn't bigger than
|
||
+ * the requested duty length. Again if such a value doesn't exist, the minimal
|
||
+ * duty length compatible with the chosen period is picked. After that the duty
|
||
+ * offset compatible with the chosen period and duty length is chosen in the
|
||
+ * same way.
|
||
+ *
|
||
* Returns: 0 on success, -EDOM if setting failed due to the exact waveform not
|
||
* being possible (if @exact), or a different negative errno on failure.
|
||
* Context: May sleep.
|