Lines Matching +full:polarity +full:- +full:active +full:- +full:low
1 // SPDX-License-Identifier: GPL-2.0
3 * STM32 Low-Power Timer Encoder and Counter driver
9 * Inspired by 104-quad-8 and stm32-timer-trigger drivers.
15 #include <linux/mfd/stm32-lptimer.h>
27 u32 polarity;
37 ret = regmap_read(priv->regmap, STM32_LPTIM_CR, &val);
51 ret = regmap_write(priv->regmap, STM32_LPTIM_CR, val);
56 clk_disable(priv->clk);
57 priv->enabled = false;
61 ret = clk_enable(priv->clk);
66 ret = regmap_write(priv->regmap, STM32_LPTIM_ARR, priv->ceiling);
70 ret = regmap_write(priv->regmap, STM32_LPTIM_CMP, 0);
75 ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
81 ret = regmap_write(priv->regmap, STM32_LPTIM_ICR,
86 priv->enabled = true;
89 return regmap_update_bits(priv->regmap, STM32_LPTIM_CR,
93 clk_disable(priv->clk);
95 regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
106 /* Setup LP timer encoder/counter and polarity, without prescaler */
107 if (priv->quadrature_mode)
111 val |= FIELD_PREP(STM32_LPTIM_CKPOL, enable ? priv->polarity : 0);
113 return regmap_update_bits(priv->regmap, STM32_LPTIM_CFGR, mask, val);
117 * In non-quadrature mode, device counts up on active edge.
119 * +---------+----------+--------------------+--------------------+
120 * | Active | Level on | IN1 signal | IN2 signal |
121 * | edge | opposite +----------+---------+----------+---------+
123 * +---------+----------+----------+---------+----------+---------+
124 * | Rising | High -> | Down | - | Up | - |
125 * | edge | Low -> | Up | - | Down | - |
126 * +---------+----------+----------+---------+----------+---------+
127 * | Falling | High -> | - | Up | - | Down |
128 * | edge | Low -> | - | Down | - | Up |
129 * +---------+----------+----------+---------+----------+---------+
130 * | Both | High -> | Down | Up | Up | Down |
131 * | edges | Low -> | Up | Down | Down | Up |
132 * +---------+----------+----------+---------+----------+---------+
153 ret = regmap_read(priv->regmap, STM32_LPTIM_CNT, &cnt);
168 if (!priv->quadrature_mode) {
173 if (priv->polarity == STM32_LPTIM_CKPOL_BOTH_EDGES) {
178 return -EINVAL;
188 return -EBUSY;
192 priv->quadrature_mode = 0;
195 priv->quadrature_mode = 1;
196 priv->polarity = STM32_LPTIM_CKPOL_BOTH_EDGES;
200 return -EINVAL;
232 return -EBUSY;
251 *ceiling = priv->ceiling;
263 return -EBUSY;
266 return -ERANGE;
268 priv->ceiling = ceiling;
295 /* LP Timer acts as up-counter on input 1 */
296 if (synapse->signal->id != count->synapses[0].signal->id) {
301 switch (priv->polarity) {
313 return -EINVAL;
320 return -EINVAL;
334 return -EBUSY;
340 /* only set polarity when in counter mode (on input 1) */
342 || synapse->signal->id != count->synapses[0].signal->id)
343 return -EINVAL;
347 priv->polarity = STM32_LPTIM_CKPOL_RISING_EDGE;
350 priv->polarity = STM32_LPTIM_CKPOL_FALLING_EDGE;
353 priv->polarity = STM32_LPTIM_CKPOL_BOTH_EDGES;
356 return -EINVAL;
418 struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent);
424 return -EINVAL;
426 counter = devm_counter_alloc(&pdev->dev, sizeof(*priv));
428 return -ENOMEM;
431 priv->dev = &pdev->dev;
432 priv->regmap = ddata->regmap;
433 priv->clk = ddata->clk;
434 priv->ceiling = STM32_LPTIM_MAX_ARR;
437 counter->name = dev_name(&pdev->dev);
438 counter->parent = &pdev->dev;
439 counter->ops = &stm32_lptim_cnt_ops;
440 if (ddata->has_encoder) {
441 counter->counts = &stm32_lptim_enc_counts;
442 counter->num_signals = ARRAY_SIZE(stm32_lptim_cnt_signals);
444 counter->counts = &stm32_lptim_in1_counts;
445 counter->num_signals = 1;
447 counter->num_counts = 1;
448 counter->signals = stm32_lptim_cnt_signals;
452 ret = devm_counter_add(&pdev->dev, counter);
454 return dev_err_probe(&pdev->dev, ret, "Failed to add counter\n");
466 if (priv->enabled) {
476 priv->enabled = true;
491 if (priv->enabled) {
492 priv->enabled = false;
510 { .compatible = "st,stm32-lptimer-counter", },
518 .name = "stm32-lptimer-counter",
526 MODULE_ALIAS("platform:stm32-lptimer-counter");