All of lore.kernel.org
 help / color / mirror / Atom feed
From: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
To: <william.gray@linaro.org>
Cc: <lee@kernel.org>, <alexandre.torgue@foss.st.com>,
	<fabrice.gasnier@foss.st.com>, <linux-iio@vger.kernel.org>,
	<linux-stm32@st-md-mailman.stormreply.com>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-kernel@vger.kernel.org>
Subject: [PATCH v5 04/10] counter: stm32-timer-cnt: introduce clock signal
Date: Thu, 7 Mar 2024 14:33:00 +0100	[thread overview]
Message-ID: <20240307133306.383045-5-fabrice.gasnier@foss.st.com> (raw)
In-Reply-To: <20240307133306.383045-1-fabrice.gasnier@foss.st.com>

Introduce the internal clock signal, used to count when in simple rising
function. Also add the "frequency" extension to the clock signal.

With this patch, signal action reports a consistent state when "increase"
function is used, and the counting frequency:
    $ echo increase > function
    $ grep -H "" signal*_action
    signal0_action:none
    signal1_action:none
    signal2_action:rising edge
    $ echo 1 > enable
    $ cat count
    25425
    $ cat count
    44439
    $ cat ../signal2/frequency
    208877930

Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
---
Changes in v5:
- removed NULL write parameter in COUNTER_COMP_FREQUENCY() macro.

Changes in v4:
- Introduce COUNTER_COMP_FREQUENCY() macro as suggested by William in [1]
[1] https://lore.kernel.org/lkml/ZZwm7ZyrL7vFn0Xd@ubuntu-server-vm-macos/
- Remove "Signal" from "Clock Signal" name which is redundant with sysfs
  path that already has signal as a name.

Changes in v3:
- split the patch in 3 parts: signal definition becomes a pre-cursor patch,
  add the "prescaler" extension in its own patch.
- Move the clock signal at the end of the signals array, so existing
  userspace programs that may rely on signal0 being "Channel 1" for
  example will remain compatible.
---
 drivers/counter/stm32-timer-cnt.c | 53 ++++++++++++++++++++++++++++---
 1 file changed, 49 insertions(+), 4 deletions(-)

diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c
index c34747d7857e..65b447b42e75 100644
--- a/drivers/counter/stm32-timer-cnt.c
+++ b/drivers/counter/stm32-timer-cnt.c
@@ -23,6 +23,7 @@
 
 #define STM32_CH1_SIG		0
 #define STM32_CH2_SIG		1
+#define STM32_CLOCK_SIG		2
 
 struct stm32_timer_regs {
 	u32 cr1;
@@ -226,6 +227,10 @@ static struct counter_comp stm32_count_ext[] = {
 			     stm32_count_ceiling_write),
 };
 
+static const enum counter_synapse_action stm32_clock_synapse_actions[] = {
+	COUNTER_SYNAPSE_ACTION_RISING_EDGE,
+};
+
 static const enum counter_synapse_action stm32_synapse_actions[] = {
 	COUNTER_SYNAPSE_ACTION_NONE,
 	COUNTER_SYNAPSE_ACTION_BOTH_EDGES
@@ -246,7 +251,10 @@ static int stm32_action_read(struct counter_device *counter,
 	switch (function) {
 	case COUNTER_FUNCTION_INCREASE:
 		/* counts on internal clock when CEN=1 */
-		*action = COUNTER_SYNAPSE_ACTION_NONE;
+		if (synapse->signal->id == STM32_CLOCK_SIG)
+			*action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
+		else
+			*action = COUNTER_SYNAPSE_ACTION_NONE;
 		return 0;
 	case COUNTER_FUNCTION_QUADRATURE_X2_A:
 		/* counts up/down on TI1FP1 edge depending on TI2FP2 level */
@@ -264,7 +272,10 @@ static int stm32_action_read(struct counter_device *counter,
 		return 0;
 	case COUNTER_FUNCTION_QUADRATURE_X4:
 		/* counts up/down on both TI1FP1 and TI2FP2 edges */
-		*action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
+		if (synapse->signal->id == STM32_CH1_SIG || synapse->signal->id == STM32_CH2_SIG)
+			*action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
+		else
+			*action = COUNTER_SYNAPSE_ACTION_NONE;
 		return 0;
 	default:
 		return -EINVAL;
@@ -279,7 +290,30 @@ static const struct counter_ops stm32_timer_cnt_ops = {
 	.action_read = stm32_action_read,
 };
 
+static int stm32_count_clk_get_freq(struct counter_device *counter,
+				    struct counter_signal *signal, u64 *freq)
+{
+	struct stm32_timer_cnt *const priv = counter_priv(counter);
+
+	*freq = clk_get_rate(priv->clk);
+
+	return 0;
+}
+
+static struct counter_comp stm32_count_clock_ext[] = {
+	COUNTER_COMP_FREQUENCY(stm32_count_clk_get_freq),
+};
+
 static struct counter_signal stm32_signals[] = {
+	/*
+	 * Need to declare all the signals as a static array, and keep the signals order here,
+	 * even if they're unused or unexisting on some timer instances. It's an abstraction,
+	 * e.g. high level view of the counter features.
+	 *
+	 * Userspace programs may rely on signal0 to be "Channel 1", signal1 to be "Channel 2",
+	 * and so on. When a signal is unexisting, the COUNTER_SYNAPSE_ACTION_NONE can be used,
+	 * to indicate that a signal doesn't affect the counter.
+	 */
 	{
 		.id = STM32_CH1_SIG,
 		.name = "Channel 1"
@@ -287,7 +321,13 @@ static struct counter_signal stm32_signals[] = {
 	{
 		.id = STM32_CH2_SIG,
 		.name = "Channel 2"
-	}
+	},
+	{
+		.id = STM32_CLOCK_SIG,
+		.name = "Clock",
+		.ext = stm32_count_clock_ext,
+		.num_ext = ARRAY_SIZE(stm32_count_clock_ext),
+	},
 };
 
 static struct counter_synapse stm32_count_synapses[] = {
@@ -300,7 +340,12 @@ static struct counter_synapse stm32_count_synapses[] = {
 		.actions_list = stm32_synapse_actions,
 		.num_actions = ARRAY_SIZE(stm32_synapse_actions),
 		.signal = &stm32_signals[STM32_CH2_SIG]
-	}
+	},
+	{
+		.actions_list = stm32_clock_synapse_actions,
+		.num_actions = ARRAY_SIZE(stm32_clock_synapse_actions),
+		.signal = &stm32_signals[STM32_CLOCK_SIG]
+	},
 };
 
 static struct counter_count stm32_counts = {
-- 
2.25.1


WARNING: multiple messages have this Message-ID (diff)
From: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
To: <william.gray@linaro.org>
Cc: <lee@kernel.org>, <alexandre.torgue@foss.st.com>,
	<fabrice.gasnier@foss.st.com>, <linux-iio@vger.kernel.org>,
	<linux-stm32@st-md-mailman.stormreply.com>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-kernel@vger.kernel.org>
Subject: [PATCH v5 04/10] counter: stm32-timer-cnt: introduce clock signal
Date: Thu, 7 Mar 2024 14:33:00 +0100	[thread overview]
Message-ID: <20240307133306.383045-5-fabrice.gasnier@foss.st.com> (raw)
In-Reply-To: <20240307133306.383045-1-fabrice.gasnier@foss.st.com>

Introduce the internal clock signal, used to count when in simple rising
function. Also add the "frequency" extension to the clock signal.

With this patch, signal action reports a consistent state when "increase"
function is used, and the counting frequency:
    $ echo increase > function
    $ grep -H "" signal*_action
    signal0_action:none
    signal1_action:none
    signal2_action:rising edge
    $ echo 1 > enable
    $ cat count
    25425
    $ cat count
    44439
    $ cat ../signal2/frequency
    208877930

Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
---
Changes in v5:
- removed NULL write parameter in COUNTER_COMP_FREQUENCY() macro.

Changes in v4:
- Introduce COUNTER_COMP_FREQUENCY() macro as suggested by William in [1]
[1] https://lore.kernel.org/lkml/ZZwm7ZyrL7vFn0Xd@ubuntu-server-vm-macos/
- Remove "Signal" from "Clock Signal" name which is redundant with sysfs
  path that already has signal as a name.

Changes in v3:
- split the patch in 3 parts: signal definition becomes a pre-cursor patch,
  add the "prescaler" extension in its own patch.
- Move the clock signal at the end of the signals array, so existing
  userspace programs that may rely on signal0 being "Channel 1" for
  example will remain compatible.
---
 drivers/counter/stm32-timer-cnt.c | 53 ++++++++++++++++++++++++++++---
 1 file changed, 49 insertions(+), 4 deletions(-)

diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c
index c34747d7857e..65b447b42e75 100644
--- a/drivers/counter/stm32-timer-cnt.c
+++ b/drivers/counter/stm32-timer-cnt.c
@@ -23,6 +23,7 @@
 
 #define STM32_CH1_SIG		0
 #define STM32_CH2_SIG		1
+#define STM32_CLOCK_SIG		2
 
 struct stm32_timer_regs {
 	u32 cr1;
@@ -226,6 +227,10 @@ static struct counter_comp stm32_count_ext[] = {
 			     stm32_count_ceiling_write),
 };
 
+static const enum counter_synapse_action stm32_clock_synapse_actions[] = {
+	COUNTER_SYNAPSE_ACTION_RISING_EDGE,
+};
+
 static const enum counter_synapse_action stm32_synapse_actions[] = {
 	COUNTER_SYNAPSE_ACTION_NONE,
 	COUNTER_SYNAPSE_ACTION_BOTH_EDGES
@@ -246,7 +251,10 @@ static int stm32_action_read(struct counter_device *counter,
 	switch (function) {
 	case COUNTER_FUNCTION_INCREASE:
 		/* counts on internal clock when CEN=1 */
-		*action = COUNTER_SYNAPSE_ACTION_NONE;
+		if (synapse->signal->id == STM32_CLOCK_SIG)
+			*action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
+		else
+			*action = COUNTER_SYNAPSE_ACTION_NONE;
 		return 0;
 	case COUNTER_FUNCTION_QUADRATURE_X2_A:
 		/* counts up/down on TI1FP1 edge depending on TI2FP2 level */
@@ -264,7 +272,10 @@ static int stm32_action_read(struct counter_device *counter,
 		return 0;
 	case COUNTER_FUNCTION_QUADRATURE_X4:
 		/* counts up/down on both TI1FP1 and TI2FP2 edges */
-		*action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
+		if (synapse->signal->id == STM32_CH1_SIG || synapse->signal->id == STM32_CH2_SIG)
+			*action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
+		else
+			*action = COUNTER_SYNAPSE_ACTION_NONE;
 		return 0;
 	default:
 		return -EINVAL;
@@ -279,7 +290,30 @@ static const struct counter_ops stm32_timer_cnt_ops = {
 	.action_read = stm32_action_read,
 };
 
+static int stm32_count_clk_get_freq(struct counter_device *counter,
+				    struct counter_signal *signal, u64 *freq)
+{
+	struct stm32_timer_cnt *const priv = counter_priv(counter);
+
+	*freq = clk_get_rate(priv->clk);
+
+	return 0;
+}
+
+static struct counter_comp stm32_count_clock_ext[] = {
+	COUNTER_COMP_FREQUENCY(stm32_count_clk_get_freq),
+};
+
 static struct counter_signal stm32_signals[] = {
+	/*
+	 * Need to declare all the signals as a static array, and keep the signals order here,
+	 * even if they're unused or unexisting on some timer instances. It's an abstraction,
+	 * e.g. high level view of the counter features.
+	 *
+	 * Userspace programs may rely on signal0 to be "Channel 1", signal1 to be "Channel 2",
+	 * and so on. When a signal is unexisting, the COUNTER_SYNAPSE_ACTION_NONE can be used,
+	 * to indicate that a signal doesn't affect the counter.
+	 */
 	{
 		.id = STM32_CH1_SIG,
 		.name = "Channel 1"
@@ -287,7 +321,13 @@ static struct counter_signal stm32_signals[] = {
 	{
 		.id = STM32_CH2_SIG,
 		.name = "Channel 2"
-	}
+	},
+	{
+		.id = STM32_CLOCK_SIG,
+		.name = "Clock",
+		.ext = stm32_count_clock_ext,
+		.num_ext = ARRAY_SIZE(stm32_count_clock_ext),
+	},
 };
 
 static struct counter_synapse stm32_count_synapses[] = {
@@ -300,7 +340,12 @@ static struct counter_synapse stm32_count_synapses[] = {
 		.actions_list = stm32_synapse_actions,
 		.num_actions = ARRAY_SIZE(stm32_synapse_actions),
 		.signal = &stm32_signals[STM32_CH2_SIG]
-	}
+	},
+	{
+		.actions_list = stm32_clock_synapse_actions,
+		.num_actions = ARRAY_SIZE(stm32_clock_synapse_actions),
+		.signal = &stm32_signals[STM32_CLOCK_SIG]
+	},
 };
 
 static struct counter_count stm32_counts = {
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2024-03-07 13:34 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-07 13:32 [PATCH v5 00/10] counter: Add stm32 timer events support Fabrice Gasnier
2024-03-07 13:32 ` Fabrice Gasnier
2024-03-07 13:32 ` [PATCH v5 01/10] counter: stm32-timer-cnt: rename quadrature signal Fabrice Gasnier
2024-03-07 13:32   ` Fabrice Gasnier
2024-03-07 13:32 ` [PATCH v5 02/10] counter: stm32-timer-cnt: rename counter Fabrice Gasnier
2024-03-07 13:32   ` Fabrice Gasnier
2024-03-07 13:32 ` [PATCH v5 03/10] counter: stm32-timer-cnt: adopt signal definitions Fabrice Gasnier
2024-03-07 13:32   ` Fabrice Gasnier
2024-03-07 13:33 ` Fabrice Gasnier [this message]
2024-03-07 13:33   ` [PATCH v5 04/10] counter: stm32-timer-cnt: introduce clock signal Fabrice Gasnier
2024-03-07 13:33 ` [PATCH v5 05/10] counter: stm32-timer-cnt: add counter prescaler extension Fabrice Gasnier
2024-03-07 13:33   ` Fabrice Gasnier
2024-03-07 13:33 ` [PATCH v5 06/10] counter: stm32-timer-cnt: add checks on quadrature encoder capability Fabrice Gasnier
2024-03-07 13:33   ` Fabrice Gasnier
2024-03-07 13:33 ` [PATCH v5 07/10] counter: stm32-timer-cnt: introduce channels Fabrice Gasnier
2024-03-07 13:33   ` Fabrice Gasnier
2024-03-07 13:33 ` [PATCH v5 08/10] counter: stm32-timer-cnt: probe number of channels from registers Fabrice Gasnier
2024-03-07 13:33   ` Fabrice Gasnier
2024-03-07 13:33 ` [PATCH v5 09/10] counter: stm32-timer-cnt: add support for overflow events Fabrice Gasnier
2024-03-07 13:33   ` Fabrice Gasnier
2024-03-07 13:33 ` [PATCH v5 10/10] counter: stm32-timer-cnt: add support for capture events Fabrice Gasnier
2024-03-07 13:33   ` Fabrice Gasnier
2024-03-07 16:09 ` [PATCH v5 00/10] counter: Add stm32 timer events support William Breathitt Gray
2024-03-07 16:09   ` William Breathitt Gray

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240307133306.383045-5-fabrice.gasnier@foss.st.com \
    --to=fabrice.gasnier@foss.st.com \
    --cc=alexandre.torgue@foss.st.com \
    --cc=lee@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-stm32@st-md-mailman.stormreply.com \
    --cc=william.gray@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.