counter: stm32-timer-cnt: probe number of channels from registers
authorFabrice Gasnier <fabrice.gasnier@foss.st.com>
Thu, 7 Mar 2024 13:33:04 +0000 (14:33 +0100)
committerWilliam Breathitt Gray <wbg@kernel.org>
Tue, 2 Apr 2024 17:10:34 +0000 (13:10 -0400)
Probe the number of capture compare channels, by writing CCER register bits
and read them back. Take care to restore the register original value.

This is a precursor patch to support capture channels.

Reviewed-by: William Breathitt Gray <william.gray@linaro.org>
Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Link: https://lore.kernel.org/r/20240307133306.383045-9-fabrice.gasnier@foss.st.com
Signed-off-by: William Breathitt Gray <william.gray@linaro.org>
drivers/counter/stm32-timer-cnt.c

index f63d0c3e3f229b3aee08f3f17c717c2692992b97..e1c0a502b74c0ad36888f34425fc1460dbc937e5 100644 (file)
@@ -42,6 +42,7 @@ struct stm32_timer_cnt {
        bool enabled;
        struct stm32_timer_regs bak;
        bool has_encoder;
+       unsigned int nchannels;
 };
 
 static const enum counter_function stm32_count_functions[] = {
@@ -416,6 +417,20 @@ static struct counter_count stm32_counts = {
        .num_ext = ARRAY_SIZE(stm32_count_ext)
 };
 
+static void stm32_timer_cnt_detect_channels(struct device *dev,
+                                           struct stm32_timer_cnt *priv)
+{
+       u32 ccer, ccer_backup;
+
+       regmap_read(priv->regmap, TIM_CCER, &ccer_backup);
+       regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE);
+       regmap_read(priv->regmap, TIM_CCER, &ccer);
+       regmap_write(priv->regmap, TIM_CCER, ccer_backup);
+       priv->nchannels = hweight32(ccer & TIM_CCER_CCXE);
+
+       dev_dbg(dev, "has %d cc channels\n", priv->nchannels);
+}
+
 /* encoder supported on TIM1 TIM2 TIM3 TIM4 TIM5 TIM8 */
 #define STM32_TIM_ENCODER_SUPPORTED    (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(7))
 
@@ -484,6 +499,8 @@ static int stm32_timer_cnt_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
+       stm32_timer_cnt_detect_channels(dev, priv);
+
        counter->name = dev_name(dev);
        counter->parent = dev;
        counter->ops = &stm32_timer_cnt_ops;