Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * STM32 Low-Power Timer Encoder and Counter driver
0004  *
0005  * Copyright (C) STMicroelectronics 2017
0006  *
0007  * Author: Fabrice Gasnier <fabrice.gasnier@st.com>
0008  *
0009  * Inspired by 104-quad-8 and stm32-timer-trigger drivers.
0010  *
0011  */
0012 
0013 #include <linux/bitfield.h>
0014 #include <linux/counter.h>
0015 #include <linux/mfd/stm32-lptimer.h>
0016 #include <linux/mod_devicetable.h>
0017 #include <linux/module.h>
0018 #include <linux/pinctrl/consumer.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/types.h>
0021 
0022 struct stm32_lptim_cnt {
0023     struct device *dev;
0024     struct regmap *regmap;
0025     struct clk *clk;
0026     u32 ceiling;
0027     u32 polarity;
0028     u32 quadrature_mode;
0029     bool enabled;
0030 };
0031 
0032 static int stm32_lptim_is_enabled(struct stm32_lptim_cnt *priv)
0033 {
0034     u32 val;
0035     int ret;
0036 
0037     ret = regmap_read(priv->regmap, STM32_LPTIM_CR, &val);
0038     if (ret)
0039         return ret;
0040 
0041     return FIELD_GET(STM32_LPTIM_ENABLE, val);
0042 }
0043 
0044 static int stm32_lptim_set_enable_state(struct stm32_lptim_cnt *priv,
0045                     int enable)
0046 {
0047     int ret;
0048     u32 val;
0049 
0050     val = FIELD_PREP(STM32_LPTIM_ENABLE, enable);
0051     ret = regmap_write(priv->regmap, STM32_LPTIM_CR, val);
0052     if (ret)
0053         return ret;
0054 
0055     if (!enable) {
0056         clk_disable(priv->clk);
0057         priv->enabled = false;
0058         return 0;
0059     }
0060 
0061     /* LP timer must be enabled before writing CMP & ARR */
0062     ret = regmap_write(priv->regmap, STM32_LPTIM_ARR, priv->ceiling);
0063     if (ret)
0064         return ret;
0065 
0066     ret = regmap_write(priv->regmap, STM32_LPTIM_CMP, 0);
0067     if (ret)
0068         return ret;
0069 
0070     /* ensure CMP & ARR registers are properly written */
0071     ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
0072                        (val & STM32_LPTIM_CMPOK_ARROK),
0073                        100, 1000);
0074     if (ret)
0075         return ret;
0076 
0077     ret = regmap_write(priv->regmap, STM32_LPTIM_ICR,
0078                STM32_LPTIM_CMPOKCF_ARROKCF);
0079     if (ret)
0080         return ret;
0081 
0082     ret = clk_enable(priv->clk);
0083     if (ret) {
0084         regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
0085         return ret;
0086     }
0087     priv->enabled = true;
0088 
0089     /* Start LP timer in continuous mode */
0090     return regmap_update_bits(priv->regmap, STM32_LPTIM_CR,
0091                   STM32_LPTIM_CNTSTRT, STM32_LPTIM_CNTSTRT);
0092 }
0093 
0094 static int stm32_lptim_setup(struct stm32_lptim_cnt *priv, int enable)
0095 {
0096     u32 mask = STM32_LPTIM_ENC | STM32_LPTIM_COUNTMODE |
0097            STM32_LPTIM_CKPOL | STM32_LPTIM_PRESC;
0098     u32 val;
0099 
0100     /* Setup LP timer encoder/counter and polarity, without prescaler */
0101     if (priv->quadrature_mode)
0102         val = enable ? STM32_LPTIM_ENC : 0;
0103     else
0104         val = enable ? STM32_LPTIM_COUNTMODE : 0;
0105     val |= FIELD_PREP(STM32_LPTIM_CKPOL, enable ? priv->polarity : 0);
0106 
0107     return regmap_update_bits(priv->regmap, STM32_LPTIM_CFGR, mask, val);
0108 }
0109 
0110 /*
0111  * In non-quadrature mode, device counts up on active edge.
0112  * In quadrature mode, encoder counting scenarios are as follows:
0113  * +---------+----------+--------------------+--------------------+
0114  * | Active  | Level on |      IN1 signal    |     IN2 signal     |
0115  * | edge    | opposite +----------+---------+----------+---------+
0116  * |         | signal   |  Rising  | Falling |  Rising  | Falling |
0117  * +---------+----------+----------+---------+----------+---------+
0118  * | Rising  | High ->  |   Down   |    -    |   Up     |    -    |
0119  * | edge    | Low  ->  |   Up     |    -    |   Down   |    -    |
0120  * +---------+----------+----------+---------+----------+---------+
0121  * | Falling | High ->  |    -     |   Up    |    -     |   Down  |
0122  * | edge    | Low  ->  |    -     |   Down  |    -     |   Up    |
0123  * +---------+----------+----------+---------+----------+---------+
0124  * | Both    | High ->  |   Down   |   Up    |   Up     |   Down  |
0125  * | edges   | Low  ->  |   Up     |   Down  |   Down   |   Up    |
0126  * +---------+----------+----------+---------+----------+---------+
0127  */
0128 static const enum counter_function stm32_lptim_cnt_functions[] = {
0129     COUNTER_FUNCTION_INCREASE,
0130     COUNTER_FUNCTION_QUADRATURE_X4,
0131 };
0132 
0133 static const enum counter_synapse_action stm32_lptim_cnt_synapse_actions[] = {
0134     COUNTER_SYNAPSE_ACTION_RISING_EDGE,
0135     COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
0136     COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
0137     COUNTER_SYNAPSE_ACTION_NONE,
0138 };
0139 
0140 static int stm32_lptim_cnt_read(struct counter_device *counter,
0141                 struct counter_count *count, u64 *val)
0142 {
0143     struct stm32_lptim_cnt *const priv = counter_priv(counter);
0144     u32 cnt;
0145     int ret;
0146 
0147     ret = regmap_read(priv->regmap, STM32_LPTIM_CNT, &cnt);
0148     if (ret)
0149         return ret;
0150 
0151     *val = cnt;
0152 
0153     return 0;
0154 }
0155 
0156 static int stm32_lptim_cnt_function_read(struct counter_device *counter,
0157                      struct counter_count *count,
0158                      enum counter_function *function)
0159 {
0160     struct stm32_lptim_cnt *const priv = counter_priv(counter);
0161 
0162     if (!priv->quadrature_mode) {
0163         *function = COUNTER_FUNCTION_INCREASE;
0164         return 0;
0165     }
0166 
0167     if (priv->polarity == STM32_LPTIM_CKPOL_BOTH_EDGES) {
0168         *function = COUNTER_FUNCTION_QUADRATURE_X4;
0169         return 0;
0170     }
0171 
0172     return -EINVAL;
0173 }
0174 
0175 static int stm32_lptim_cnt_function_write(struct counter_device *counter,
0176                       struct counter_count *count,
0177                       enum counter_function function)
0178 {
0179     struct stm32_lptim_cnt *const priv = counter_priv(counter);
0180 
0181     if (stm32_lptim_is_enabled(priv))
0182         return -EBUSY;
0183 
0184     switch (function) {
0185     case COUNTER_FUNCTION_INCREASE:
0186         priv->quadrature_mode = 0;
0187         return 0;
0188     case COUNTER_FUNCTION_QUADRATURE_X4:
0189         priv->quadrature_mode = 1;
0190         priv->polarity = STM32_LPTIM_CKPOL_BOTH_EDGES;
0191         return 0;
0192     default:
0193         /* should never reach this path */
0194         return -EINVAL;
0195     }
0196 }
0197 
0198 static int stm32_lptim_cnt_enable_read(struct counter_device *counter,
0199                        struct counter_count *count,
0200                        u8 *enable)
0201 {
0202     struct stm32_lptim_cnt *const priv = counter_priv(counter);
0203     int ret;
0204 
0205     ret = stm32_lptim_is_enabled(priv);
0206     if (ret < 0)
0207         return ret;
0208 
0209     *enable = ret;
0210 
0211     return 0;
0212 }
0213 
0214 static int stm32_lptim_cnt_enable_write(struct counter_device *counter,
0215                     struct counter_count *count,
0216                     u8 enable)
0217 {
0218     struct stm32_lptim_cnt *const priv = counter_priv(counter);
0219     int ret;
0220 
0221     /* Check nobody uses the timer, or already disabled/enabled */
0222     ret = stm32_lptim_is_enabled(priv);
0223     if ((ret < 0) || (!ret && !enable))
0224         return ret;
0225     if (enable && ret)
0226         return -EBUSY;
0227 
0228     ret = stm32_lptim_setup(priv, enable);
0229     if (ret)
0230         return ret;
0231 
0232     ret = stm32_lptim_set_enable_state(priv, enable);
0233     if (ret)
0234         return ret;
0235 
0236     return 0;
0237 }
0238 
0239 static int stm32_lptim_cnt_ceiling_read(struct counter_device *counter,
0240                     struct counter_count *count,
0241                     u64 *ceiling)
0242 {
0243     struct stm32_lptim_cnt *const priv = counter_priv(counter);
0244 
0245     *ceiling = priv->ceiling;
0246 
0247     return 0;
0248 }
0249 
0250 static int stm32_lptim_cnt_ceiling_write(struct counter_device *counter,
0251                      struct counter_count *count,
0252                      u64 ceiling)
0253 {
0254     struct stm32_lptim_cnt *const priv = counter_priv(counter);
0255 
0256     if (stm32_lptim_is_enabled(priv))
0257         return -EBUSY;
0258 
0259     if (ceiling > STM32_LPTIM_MAX_ARR)
0260         return -ERANGE;
0261 
0262     priv->ceiling = ceiling;
0263 
0264     return 0;
0265 }
0266 
0267 static struct counter_comp stm32_lptim_cnt_ext[] = {
0268     COUNTER_COMP_ENABLE(stm32_lptim_cnt_enable_read,
0269                 stm32_lptim_cnt_enable_write),
0270     COUNTER_COMP_CEILING(stm32_lptim_cnt_ceiling_read,
0271                  stm32_lptim_cnt_ceiling_write),
0272 };
0273 
0274 static int stm32_lptim_cnt_action_read(struct counter_device *counter,
0275                        struct counter_count *count,
0276                        struct counter_synapse *synapse,
0277                        enum counter_synapse_action *action)
0278 {
0279     struct stm32_lptim_cnt *const priv = counter_priv(counter);
0280     enum counter_function function;
0281     int err;
0282 
0283     err = stm32_lptim_cnt_function_read(counter, count, &function);
0284     if (err)
0285         return err;
0286 
0287     switch (function) {
0288     case COUNTER_FUNCTION_INCREASE:
0289         /* LP Timer acts as up-counter on input 1 */
0290         if (synapse->signal->id != count->synapses[0].signal->id) {
0291             *action = COUNTER_SYNAPSE_ACTION_NONE;
0292             return 0;
0293         }
0294 
0295         switch (priv->polarity) {
0296         case STM32_LPTIM_CKPOL_RISING_EDGE:
0297             *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
0298             return 0;
0299         case STM32_LPTIM_CKPOL_FALLING_EDGE:
0300             *action = COUNTER_SYNAPSE_ACTION_FALLING_EDGE;
0301             return 0;
0302         case STM32_LPTIM_CKPOL_BOTH_EDGES:
0303             *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
0304             return 0;
0305         default:
0306             /* should never reach this path */
0307             return -EINVAL;
0308         }
0309     case COUNTER_FUNCTION_QUADRATURE_X4:
0310         *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
0311         return 0;
0312     default:
0313         /* should never reach this path */
0314         return -EINVAL;
0315     }
0316 }
0317 
0318 static int stm32_lptim_cnt_action_write(struct counter_device *counter,
0319                     struct counter_count *count,
0320                     struct counter_synapse *synapse,
0321                     enum counter_synapse_action action)
0322 {
0323     struct stm32_lptim_cnt *const priv = counter_priv(counter);
0324     enum counter_function function;
0325     int err;
0326 
0327     if (stm32_lptim_is_enabled(priv))
0328         return -EBUSY;
0329 
0330     err = stm32_lptim_cnt_function_read(counter, count, &function);
0331     if (err)
0332         return err;
0333 
0334     /* only set polarity when in counter mode (on input 1) */
0335     if (function != COUNTER_FUNCTION_INCREASE
0336         || synapse->signal->id != count->synapses[0].signal->id)
0337         return -EINVAL;
0338 
0339     switch (action) {
0340     case COUNTER_SYNAPSE_ACTION_RISING_EDGE:
0341         priv->polarity = STM32_LPTIM_CKPOL_RISING_EDGE;
0342         return 0;
0343     case COUNTER_SYNAPSE_ACTION_FALLING_EDGE:
0344         priv->polarity = STM32_LPTIM_CKPOL_FALLING_EDGE;
0345         return 0;
0346     case COUNTER_SYNAPSE_ACTION_BOTH_EDGES:
0347         priv->polarity = STM32_LPTIM_CKPOL_BOTH_EDGES;
0348         return 0;
0349     default:
0350         return -EINVAL;
0351     }
0352 }
0353 
0354 static const struct counter_ops stm32_lptim_cnt_ops = {
0355     .count_read = stm32_lptim_cnt_read,
0356     .function_read = stm32_lptim_cnt_function_read,
0357     .function_write = stm32_lptim_cnt_function_write,
0358     .action_read = stm32_lptim_cnt_action_read,
0359     .action_write = stm32_lptim_cnt_action_write,
0360 };
0361 
0362 static struct counter_signal stm32_lptim_cnt_signals[] = {
0363     {
0364         .id = 0,
0365         .name = "Channel 1 Quadrature A"
0366     },
0367     {
0368         .id = 1,
0369         .name = "Channel 1 Quadrature B"
0370     }
0371 };
0372 
0373 static struct counter_synapse stm32_lptim_cnt_synapses[] = {
0374     {
0375         .actions_list = stm32_lptim_cnt_synapse_actions,
0376         .num_actions = ARRAY_SIZE(stm32_lptim_cnt_synapse_actions),
0377         .signal = &stm32_lptim_cnt_signals[0]
0378     },
0379     {
0380         .actions_list = stm32_lptim_cnt_synapse_actions,
0381         .num_actions = ARRAY_SIZE(stm32_lptim_cnt_synapse_actions),
0382         .signal = &stm32_lptim_cnt_signals[1]
0383     }
0384 };
0385 
0386 /* LP timer with encoder */
0387 static struct counter_count stm32_lptim_enc_counts = {
0388     .id = 0,
0389     .name = "LPTimer Count",
0390     .functions_list = stm32_lptim_cnt_functions,
0391     .num_functions = ARRAY_SIZE(stm32_lptim_cnt_functions),
0392     .synapses = stm32_lptim_cnt_synapses,
0393     .num_synapses = ARRAY_SIZE(stm32_lptim_cnt_synapses),
0394     .ext = stm32_lptim_cnt_ext,
0395     .num_ext = ARRAY_SIZE(stm32_lptim_cnt_ext)
0396 };
0397 
0398 /* LP timer without encoder (counter only) */
0399 static struct counter_count stm32_lptim_in1_counts = {
0400     .id = 0,
0401     .name = "LPTimer Count",
0402     .functions_list = stm32_lptim_cnt_functions,
0403     .num_functions = 1,
0404     .synapses = stm32_lptim_cnt_synapses,
0405     .num_synapses = 1,
0406     .ext = stm32_lptim_cnt_ext,
0407     .num_ext = ARRAY_SIZE(stm32_lptim_cnt_ext)
0408 };
0409 
0410 static int stm32_lptim_cnt_probe(struct platform_device *pdev)
0411 {
0412     struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent);
0413     struct counter_device *counter;
0414     struct stm32_lptim_cnt *priv;
0415     int ret;
0416 
0417     if (IS_ERR_OR_NULL(ddata))
0418         return -EINVAL;
0419 
0420     counter = devm_counter_alloc(&pdev->dev, sizeof(*priv));
0421     if (!counter)
0422         return -ENOMEM;
0423     priv = counter_priv(counter);
0424 
0425     priv->dev = &pdev->dev;
0426     priv->regmap = ddata->regmap;
0427     priv->clk = ddata->clk;
0428     priv->ceiling = STM32_LPTIM_MAX_ARR;
0429 
0430     /* Initialize Counter device */
0431     counter->name = dev_name(&pdev->dev);
0432     counter->parent = &pdev->dev;
0433     counter->ops = &stm32_lptim_cnt_ops;
0434     if (ddata->has_encoder) {
0435         counter->counts = &stm32_lptim_enc_counts;
0436         counter->num_signals = ARRAY_SIZE(stm32_lptim_cnt_signals);
0437     } else {
0438         counter->counts = &stm32_lptim_in1_counts;
0439         counter->num_signals = 1;
0440     }
0441     counter->num_counts = 1;
0442     counter->signals = stm32_lptim_cnt_signals;
0443 
0444     platform_set_drvdata(pdev, priv);
0445 
0446     ret = devm_counter_add(&pdev->dev, counter);
0447     if (ret < 0)
0448         return dev_err_probe(&pdev->dev, ret, "Failed to add counter\n");
0449 
0450     return 0;
0451 }
0452 
0453 #ifdef CONFIG_PM_SLEEP
0454 static int stm32_lptim_cnt_suspend(struct device *dev)
0455 {
0456     struct stm32_lptim_cnt *priv = dev_get_drvdata(dev);
0457     int ret;
0458 
0459     /* Only take care of enabled counter: don't disturb other MFD child */
0460     if (priv->enabled) {
0461         ret = stm32_lptim_setup(priv, 0);
0462         if (ret)
0463             return ret;
0464 
0465         ret = stm32_lptim_set_enable_state(priv, 0);
0466         if (ret)
0467             return ret;
0468 
0469         /* Force enable state for later resume */
0470         priv->enabled = true;
0471     }
0472 
0473     return pinctrl_pm_select_sleep_state(dev);
0474 }
0475 
0476 static int stm32_lptim_cnt_resume(struct device *dev)
0477 {
0478     struct stm32_lptim_cnt *priv = dev_get_drvdata(dev);
0479     int ret;
0480 
0481     ret = pinctrl_pm_select_default_state(dev);
0482     if (ret)
0483         return ret;
0484 
0485     if (priv->enabled) {
0486         priv->enabled = false;
0487         ret = stm32_lptim_setup(priv, 1);
0488         if (ret)
0489             return ret;
0490 
0491         ret = stm32_lptim_set_enable_state(priv, 1);
0492         if (ret)
0493             return ret;
0494     }
0495 
0496     return 0;
0497 }
0498 #endif
0499 
0500 static SIMPLE_DEV_PM_OPS(stm32_lptim_cnt_pm_ops, stm32_lptim_cnt_suspend,
0501              stm32_lptim_cnt_resume);
0502 
0503 static const struct of_device_id stm32_lptim_cnt_of_match[] = {
0504     { .compatible = "st,stm32-lptimer-counter", },
0505     {},
0506 };
0507 MODULE_DEVICE_TABLE(of, stm32_lptim_cnt_of_match);
0508 
0509 static struct platform_driver stm32_lptim_cnt_driver = {
0510     .probe = stm32_lptim_cnt_probe,
0511     .driver = {
0512         .name = "stm32-lptimer-counter",
0513         .of_match_table = stm32_lptim_cnt_of_match,
0514         .pm = &stm32_lptim_cnt_pm_ops,
0515     },
0516 };
0517 module_platform_driver(stm32_lptim_cnt_driver);
0518 
0519 MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");
0520 MODULE_ALIAS("platform:stm32-lptimer-counter");
0521 MODULE_DESCRIPTION("STMicroelectronics STM32 LPTIM counter driver");
0522 MODULE_LICENSE("GPL v2");