linux/drivers/counter/stm32-timer-cnt.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * STM32 Timer Encoder and Counter driver
   4 *
   5 * Copyright (C) STMicroelectronics 2018
   6 *
   7 * Author: Benjamin Gaignard <benjamin.gaignard@st.com>
   8 *
   9 */
  10#include <linux/counter.h>
  11#include <linux/mfd/stm32-timers.h>
  12#include <linux/mod_devicetable.h>
  13#include <linux/module.h>
  14#include <linux/pinctrl/consumer.h>
  15#include <linux/platform_device.h>
  16
  17#define TIM_CCMR_CCXS   (BIT(8) | BIT(0))
  18#define TIM_CCMR_MASK   (TIM_CCMR_CC1S | TIM_CCMR_CC2S | \
  19                         TIM_CCMR_IC1F | TIM_CCMR_IC2F)
  20#define TIM_CCER_MASK   (TIM_CCER_CC1P | TIM_CCER_CC1NP | \
  21                         TIM_CCER_CC2P | TIM_CCER_CC2NP)
  22
  23struct stm32_timer_regs {
  24        u32 cr1;
  25        u32 cnt;
  26        u32 smcr;
  27        u32 arr;
  28};
  29
  30struct stm32_timer_cnt {
  31        struct counter_device counter;
  32        struct regmap *regmap;
  33        struct clk *clk;
  34        u32 max_arr;
  35        bool enabled;
  36        struct stm32_timer_regs bak;
  37};
  38
  39/**
  40 * enum stm32_count_function - enumerates stm32 timer counter encoder modes
  41 * @STM32_COUNT_SLAVE_MODE_DISABLED: counts on internal clock when CEN=1
  42 * @STM32_COUNT_ENCODER_MODE_1: counts TI1FP1 edges, depending on TI2FP2 level
  43 * @STM32_COUNT_ENCODER_MODE_2: counts TI2FP2 edges, depending on TI1FP1 level
  44 * @STM32_COUNT_ENCODER_MODE_3: counts on both TI1FP1 and TI2FP2 edges
  45 */
  46enum stm32_count_function {
  47        STM32_COUNT_SLAVE_MODE_DISABLED,
  48        STM32_COUNT_ENCODER_MODE_1,
  49        STM32_COUNT_ENCODER_MODE_2,
  50        STM32_COUNT_ENCODER_MODE_3,
  51};
  52
  53static const enum counter_function stm32_count_functions[] = {
  54        [STM32_COUNT_SLAVE_MODE_DISABLED] = COUNTER_FUNCTION_INCREASE,
  55        [STM32_COUNT_ENCODER_MODE_1] = COUNTER_FUNCTION_QUADRATURE_X2_A,
  56        [STM32_COUNT_ENCODER_MODE_2] = COUNTER_FUNCTION_QUADRATURE_X2_B,
  57        [STM32_COUNT_ENCODER_MODE_3] = COUNTER_FUNCTION_QUADRATURE_X4,
  58};
  59
  60static int stm32_count_read(struct counter_device *counter,
  61                            struct counter_count *count, unsigned long *val)
  62{
  63        struct stm32_timer_cnt *const priv = counter->priv;
  64        u32 cnt;
  65
  66        regmap_read(priv->regmap, TIM_CNT, &cnt);
  67        *val = cnt;
  68
  69        return 0;
  70}
  71
  72static int stm32_count_write(struct counter_device *counter,
  73                             struct counter_count *count,
  74                             const unsigned long val)
  75{
  76        struct stm32_timer_cnt *const priv = counter->priv;
  77        u32 ceiling;
  78
  79        regmap_read(priv->regmap, TIM_ARR, &ceiling);
  80        if (val > ceiling)
  81                return -EINVAL;
  82
  83        return regmap_write(priv->regmap, TIM_CNT, val);
  84}
  85
  86static int stm32_count_function_get(struct counter_device *counter,
  87                                    struct counter_count *count,
  88                                    size_t *function)
  89{
  90        struct stm32_timer_cnt *const priv = counter->priv;
  91        u32 smcr;
  92
  93        regmap_read(priv->regmap, TIM_SMCR, &smcr);
  94
  95        switch (smcr & TIM_SMCR_SMS) {
  96        case 0:
  97                *function = STM32_COUNT_SLAVE_MODE_DISABLED;
  98                return 0;
  99        case 1:
 100                *function = STM32_COUNT_ENCODER_MODE_1;
 101                return 0;
 102        case 2:
 103                *function = STM32_COUNT_ENCODER_MODE_2;
 104                return 0;
 105        case 3:
 106                *function = STM32_COUNT_ENCODER_MODE_3;
 107                return 0;
 108        default:
 109                return -EINVAL;
 110        }
 111}
 112
 113static int stm32_count_function_set(struct counter_device *counter,
 114                                    struct counter_count *count,
 115                                    size_t function)
 116{
 117        struct stm32_timer_cnt *const priv = counter->priv;
 118        u32 cr1, sms;
 119
 120        switch (function) {
 121        case STM32_COUNT_SLAVE_MODE_DISABLED:
 122                sms = 0;
 123                break;
 124        case STM32_COUNT_ENCODER_MODE_1:
 125                sms = 1;
 126                break;
 127        case STM32_COUNT_ENCODER_MODE_2:
 128                sms = 2;
 129                break;
 130        case STM32_COUNT_ENCODER_MODE_3:
 131                sms = 3;
 132                break;
 133        default:
 134                return -EINVAL;
 135        }
 136
 137        /* Store enable status */
 138        regmap_read(priv->regmap, TIM_CR1, &cr1);
 139
 140        regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
 141
 142        regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, sms);
 143
 144        /* Make sure that registers are updated */
 145        regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
 146
 147        /* Restore the enable status */
 148        regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, cr1);
 149
 150        return 0;
 151}
 152
 153static ssize_t stm32_count_direction_read(struct counter_device *counter,
 154                                      struct counter_count *count,
 155                                      void *private, char *buf)
 156{
 157        struct stm32_timer_cnt *const priv = counter->priv;
 158        const char *direction;
 159        u32 cr1;
 160
 161        regmap_read(priv->regmap, TIM_CR1, &cr1);
 162        direction = (cr1 & TIM_CR1_DIR) ? "backward" : "forward";
 163
 164        return scnprintf(buf, PAGE_SIZE, "%s\n", direction);
 165}
 166
 167static ssize_t stm32_count_ceiling_read(struct counter_device *counter,
 168                                        struct counter_count *count,
 169                                        void *private, char *buf)
 170{
 171        struct stm32_timer_cnt *const priv = counter->priv;
 172        u32 arr;
 173
 174        regmap_read(priv->regmap, TIM_ARR, &arr);
 175
 176        return snprintf(buf, PAGE_SIZE, "%u\n", arr);
 177}
 178
 179static ssize_t stm32_count_ceiling_write(struct counter_device *counter,
 180                                         struct counter_count *count,
 181                                         void *private,
 182                                         const char *buf, size_t len)
 183{
 184        struct stm32_timer_cnt *const priv = counter->priv;
 185        unsigned int ceiling;
 186        int ret;
 187
 188        ret = kstrtouint(buf, 0, &ceiling);
 189        if (ret)
 190                return ret;
 191
 192        if (ceiling > priv->max_arr)
 193                return -ERANGE;
 194
 195        /* TIMx_ARR register shouldn't be buffered (ARPE=0) */
 196        regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0);
 197        regmap_write(priv->regmap, TIM_ARR, ceiling);
 198
 199        return len;
 200}
 201
 202static ssize_t stm32_count_enable_read(struct counter_device *counter,
 203                                       struct counter_count *count,
 204                                       void *private, char *buf)
 205{
 206        struct stm32_timer_cnt *const priv = counter->priv;
 207        u32 cr1;
 208
 209        regmap_read(priv->regmap, TIM_CR1, &cr1);
 210
 211        return scnprintf(buf, PAGE_SIZE, "%d\n", (bool)(cr1 & TIM_CR1_CEN));
 212}
 213
 214static ssize_t stm32_count_enable_write(struct counter_device *counter,
 215                                        struct counter_count *count,
 216                                        void *private,
 217                                        const char *buf, size_t len)
 218{
 219        struct stm32_timer_cnt *const priv = counter->priv;
 220        int err;
 221        u32 cr1;
 222        bool enable;
 223
 224        err = kstrtobool(buf, &enable);
 225        if (err)
 226                return err;
 227
 228        if (enable) {
 229                regmap_read(priv->regmap, TIM_CR1, &cr1);
 230                if (!(cr1 & TIM_CR1_CEN))
 231                        clk_enable(priv->clk);
 232
 233                regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN,
 234                                   TIM_CR1_CEN);
 235        } else {
 236                regmap_read(priv->regmap, TIM_CR1, &cr1);
 237                regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
 238                if (cr1 & TIM_CR1_CEN)
 239                        clk_disable(priv->clk);
 240        }
 241
 242        /* Keep enabled state to properly handle low power states */
 243        priv->enabled = enable;
 244
 245        return len;
 246}
 247
 248static const struct counter_count_ext stm32_count_ext[] = {
 249        {
 250                .name = "direction",
 251                .read = stm32_count_direction_read,
 252        },
 253        {
 254                .name = "enable",
 255                .read = stm32_count_enable_read,
 256                .write = stm32_count_enable_write
 257        },
 258        {
 259                .name = "ceiling",
 260                .read = stm32_count_ceiling_read,
 261                .write = stm32_count_ceiling_write
 262        },
 263};
 264
 265enum stm32_synapse_action {
 266        STM32_SYNAPSE_ACTION_NONE,
 267        STM32_SYNAPSE_ACTION_BOTH_EDGES
 268};
 269
 270static const enum counter_synapse_action stm32_synapse_actions[] = {
 271        [STM32_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE,
 272        [STM32_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES
 273};
 274
 275static int stm32_action_get(struct counter_device *counter,
 276                            struct counter_count *count,
 277                            struct counter_synapse *synapse,
 278                            size_t *action)
 279{
 280        size_t function;
 281        int err;
 282
 283        err = stm32_count_function_get(counter, count, &function);
 284        if (err)
 285                return err;
 286
 287        switch (function) {
 288        case STM32_COUNT_SLAVE_MODE_DISABLED:
 289                /* counts on internal clock when CEN=1 */
 290                *action = STM32_SYNAPSE_ACTION_NONE;
 291                return 0;
 292        case STM32_COUNT_ENCODER_MODE_1:
 293                /* counts up/down on TI1FP1 edge depending on TI2FP2 level */
 294                if (synapse->signal->id == count->synapses[0].signal->id)
 295                        *action = STM32_SYNAPSE_ACTION_BOTH_EDGES;
 296                else
 297                        *action = STM32_SYNAPSE_ACTION_NONE;
 298                return 0;
 299        case STM32_COUNT_ENCODER_MODE_2:
 300                /* counts up/down on TI2FP2 edge depending on TI1FP1 level */
 301                if (synapse->signal->id == count->synapses[1].signal->id)
 302                        *action = STM32_SYNAPSE_ACTION_BOTH_EDGES;
 303                else
 304                        *action = STM32_SYNAPSE_ACTION_NONE;
 305                return 0;
 306        case STM32_COUNT_ENCODER_MODE_3:
 307                /* counts up/down on both TI1FP1 and TI2FP2 edges */
 308                *action = STM32_SYNAPSE_ACTION_BOTH_EDGES;
 309                return 0;
 310        default:
 311                return -EINVAL;
 312        }
 313}
 314
 315static const struct counter_ops stm32_timer_cnt_ops = {
 316        .count_read = stm32_count_read,
 317        .count_write = stm32_count_write,
 318        .function_get = stm32_count_function_get,
 319        .function_set = stm32_count_function_set,
 320        .action_get = stm32_action_get,
 321};
 322
 323static struct counter_signal stm32_signals[] = {
 324        {
 325                .id = 0,
 326                .name = "Channel 1 Quadrature A"
 327        },
 328        {
 329                .id = 1,
 330                .name = "Channel 1 Quadrature B"
 331        }
 332};
 333
 334static struct counter_synapse stm32_count_synapses[] = {
 335        {
 336                .actions_list = stm32_synapse_actions,
 337                .num_actions = ARRAY_SIZE(stm32_synapse_actions),
 338                .signal = &stm32_signals[0]
 339        },
 340        {
 341                .actions_list = stm32_synapse_actions,
 342                .num_actions = ARRAY_SIZE(stm32_synapse_actions),
 343                .signal = &stm32_signals[1]
 344        }
 345};
 346
 347static struct counter_count stm32_counts = {
 348        .id = 0,
 349        .name = "Channel 1 Count",
 350        .functions_list = stm32_count_functions,
 351        .num_functions = ARRAY_SIZE(stm32_count_functions),
 352        .synapses = stm32_count_synapses,
 353        .num_synapses = ARRAY_SIZE(stm32_count_synapses),
 354        .ext = stm32_count_ext,
 355        .num_ext = ARRAY_SIZE(stm32_count_ext)
 356};
 357
 358static int stm32_timer_cnt_probe(struct platform_device *pdev)
 359{
 360        struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent);
 361        struct device *dev = &pdev->dev;
 362        struct stm32_timer_cnt *priv;
 363
 364        if (IS_ERR_OR_NULL(ddata))
 365                return -EINVAL;
 366
 367        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 368        if (!priv)
 369                return -ENOMEM;
 370
 371        priv->regmap = ddata->regmap;
 372        priv->clk = ddata->clk;
 373        priv->max_arr = ddata->max_arr;
 374
 375        priv->counter.name = dev_name(dev);
 376        priv->counter.parent = dev;
 377        priv->counter.ops = &stm32_timer_cnt_ops;
 378        priv->counter.counts = &stm32_counts;
 379        priv->counter.num_counts = 1;
 380        priv->counter.signals = stm32_signals;
 381        priv->counter.num_signals = ARRAY_SIZE(stm32_signals);
 382        priv->counter.priv = priv;
 383
 384        platform_set_drvdata(pdev, priv);
 385
 386        /* Register Counter device */
 387        return devm_counter_register(dev, &priv->counter);
 388}
 389
 390static int __maybe_unused stm32_timer_cnt_suspend(struct device *dev)
 391{
 392        struct stm32_timer_cnt *priv = dev_get_drvdata(dev);
 393
 394        /* Only take care of enabled counter: don't disturb other MFD child */
 395        if (priv->enabled) {
 396                /* Backup registers that may get lost in low power mode */
 397                regmap_read(priv->regmap, TIM_SMCR, &priv->bak.smcr);
 398                regmap_read(priv->regmap, TIM_ARR, &priv->bak.arr);
 399                regmap_read(priv->regmap, TIM_CNT, &priv->bak.cnt);
 400                regmap_read(priv->regmap, TIM_CR1, &priv->bak.cr1);
 401
 402                /* Disable the counter */
 403                regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
 404                clk_disable(priv->clk);
 405        }
 406
 407        return pinctrl_pm_select_sleep_state(dev);
 408}
 409
 410static int __maybe_unused stm32_timer_cnt_resume(struct device *dev)
 411{
 412        struct stm32_timer_cnt *priv = dev_get_drvdata(dev);
 413        int ret;
 414
 415        ret = pinctrl_pm_select_default_state(dev);
 416        if (ret)
 417                return ret;
 418
 419        if (priv->enabled) {
 420                clk_enable(priv->clk);
 421
 422                /* Restore registers that may have been lost */
 423                regmap_write(priv->regmap, TIM_SMCR, priv->bak.smcr);
 424                regmap_write(priv->regmap, TIM_ARR, priv->bak.arr);
 425                regmap_write(priv->regmap, TIM_CNT, priv->bak.cnt);
 426
 427                /* Also re-enables the counter */
 428                regmap_write(priv->regmap, TIM_CR1, priv->bak.cr1);
 429        }
 430
 431        return 0;
 432}
 433
 434static SIMPLE_DEV_PM_OPS(stm32_timer_cnt_pm_ops, stm32_timer_cnt_suspend,
 435                         stm32_timer_cnt_resume);
 436
 437static const struct of_device_id stm32_timer_cnt_of_match[] = {
 438        { .compatible = "st,stm32-timer-counter", },
 439        {},
 440};
 441MODULE_DEVICE_TABLE(of, stm32_timer_cnt_of_match);
 442
 443static struct platform_driver stm32_timer_cnt_driver = {
 444        .probe = stm32_timer_cnt_probe,
 445        .driver = {
 446                .name = "stm32-timer-counter",
 447                .of_match_table = stm32_timer_cnt_of_match,
 448                .pm = &stm32_timer_cnt_pm_ops,
 449        },
 450};
 451module_platform_driver(stm32_timer_cnt_driver);
 452
 453MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
 454MODULE_ALIAS("platform:stm32-timer-counter");
 455MODULE_DESCRIPTION("STMicroelectronics STM32 TIMER counter driver");
 456MODULE_LICENSE("GPL v2");
 457