Lines Matching +full:up +full:- +full:counter
1 // SPDX-License-Identifier: GPL-2.0
3 * STM32 Timer Encoder and Counter driver
10 #include <linux/counter.h>
11 #include <linux/mfd/stm32-timers.h>
46 static int stm32_count_read(struct counter_device *counter, in stm32_count_read() argument
49 struct stm32_timer_cnt *const priv = counter_priv(counter); in stm32_count_read()
52 regmap_read(priv->regmap, TIM_CNT, &cnt); in stm32_count_read()
58 static int stm32_count_write(struct counter_device *counter, in stm32_count_write() argument
61 struct stm32_timer_cnt *const priv = counter_priv(counter); in stm32_count_write()
64 regmap_read(priv->regmap, TIM_ARR, &ceiling); in stm32_count_write()
66 return -EINVAL; in stm32_count_write()
68 return regmap_write(priv->regmap, TIM_CNT, val); in stm32_count_write()
71 static int stm32_count_function_read(struct counter_device *counter, in stm32_count_function_read() argument
75 struct stm32_timer_cnt *const priv = counter_priv(counter); in stm32_count_function_read()
78 regmap_read(priv->regmap, TIM_SMCR, &smcr); in stm32_count_function_read()
94 return -EINVAL; in stm32_count_function_read()
98 static int stm32_count_function_write(struct counter_device *counter, in stm32_count_function_write() argument
102 struct stm32_timer_cnt *const priv = counter_priv(counter); in stm32_count_function_write()
119 return -EINVAL; in stm32_count_function_write()
123 regmap_read(priv->regmap, TIM_CR1, &cr1); in stm32_count_function_write()
125 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); in stm32_count_function_write()
127 regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, sms); in stm32_count_function_write()
130 regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); in stm32_count_function_write()
133 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, cr1); in stm32_count_function_write()
138 static int stm32_count_direction_read(struct counter_device *counter, in stm32_count_direction_read() argument
142 struct stm32_timer_cnt *const priv = counter_priv(counter); in stm32_count_direction_read()
145 regmap_read(priv->regmap, TIM_CR1, &cr1); in stm32_count_direction_read()
152 static int stm32_count_ceiling_read(struct counter_device *counter, in stm32_count_ceiling_read() argument
155 struct stm32_timer_cnt *const priv = counter_priv(counter); in stm32_count_ceiling_read()
158 regmap_read(priv->regmap, TIM_ARR, &arr); in stm32_count_ceiling_read()
165 static int stm32_count_ceiling_write(struct counter_device *counter, in stm32_count_ceiling_write() argument
168 struct stm32_timer_cnt *const priv = counter_priv(counter); in stm32_count_ceiling_write()
170 if (ceiling > priv->max_arr) in stm32_count_ceiling_write()
171 return -ERANGE; in stm32_count_ceiling_write()
174 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0); in stm32_count_ceiling_write()
175 regmap_write(priv->regmap, TIM_ARR, ceiling); in stm32_count_ceiling_write()
180 static int stm32_count_enable_read(struct counter_device *counter, in stm32_count_enable_read() argument
183 struct stm32_timer_cnt *const priv = counter_priv(counter); in stm32_count_enable_read()
186 regmap_read(priv->regmap, TIM_CR1, &cr1); in stm32_count_enable_read()
193 static int stm32_count_enable_write(struct counter_device *counter, in stm32_count_enable_write() argument
196 struct stm32_timer_cnt *const priv = counter_priv(counter); in stm32_count_enable_write()
200 regmap_read(priv->regmap, TIM_CR1, &cr1); in stm32_count_enable_write()
202 clk_enable(priv->clk); in stm32_count_enable_write()
204 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, in stm32_count_enable_write()
207 regmap_read(priv->regmap, TIM_CR1, &cr1); in stm32_count_enable_write()
208 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); in stm32_count_enable_write()
210 clk_disable(priv->clk); in stm32_count_enable_write()
214 priv->enabled = enable; in stm32_count_enable_write()
231 static int stm32_action_read(struct counter_device *counter, in stm32_action_read() argument
239 err = stm32_count_function_read(counter, count, &function); in stm32_action_read()
249 /* counts up/down on TI1FP1 edge depending on TI2FP2 level */ in stm32_action_read()
250 if (synapse->signal->id == count->synapses[0].signal->id) in stm32_action_read()
256 /* counts up/down on TI2FP2 edge depending on TI1FP1 level */ in stm32_action_read()
257 if (synapse->signal->id == count->synapses[1].signal->id) in stm32_action_read()
263 /* counts up/down on both TI1FP1 and TI2FP2 edges */ in stm32_action_read()
267 return -EINVAL; in stm32_action_read()
316 struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent); in stm32_timer_cnt_probe()
317 struct device *dev = &pdev->dev; in stm32_timer_cnt_probe()
319 struct counter_device *counter; in stm32_timer_cnt_probe() local
323 return -EINVAL; in stm32_timer_cnt_probe()
325 counter = devm_counter_alloc(dev, sizeof(*priv)); in stm32_timer_cnt_probe()
326 if (!counter) in stm32_timer_cnt_probe()
327 return -ENOMEM; in stm32_timer_cnt_probe()
329 priv = counter_priv(counter); in stm32_timer_cnt_probe()
331 priv->regmap = ddata->regmap; in stm32_timer_cnt_probe()
332 priv->clk = ddata->clk; in stm32_timer_cnt_probe()
333 priv->max_arr = ddata->max_arr; in stm32_timer_cnt_probe()
335 counter->name = dev_name(dev); in stm32_timer_cnt_probe()
336 counter->parent = dev; in stm32_timer_cnt_probe()
337 counter->ops = &stm32_timer_cnt_ops; in stm32_timer_cnt_probe()
338 counter->counts = &stm32_counts; in stm32_timer_cnt_probe()
339 counter->num_counts = 1; in stm32_timer_cnt_probe()
340 counter->signals = stm32_signals; in stm32_timer_cnt_probe()
341 counter->num_signals = ARRAY_SIZE(stm32_signals); in stm32_timer_cnt_probe()
345 /* Register Counter device */ in stm32_timer_cnt_probe()
346 ret = devm_counter_add(dev, counter); in stm32_timer_cnt_probe()
348 dev_err_probe(dev, ret, "Failed to add counter\n"); in stm32_timer_cnt_probe()
357 /* Only take care of enabled counter: don't disturb other MFD child */ in stm32_timer_cnt_suspend()
358 if (priv->enabled) { in stm32_timer_cnt_suspend()
360 regmap_read(priv->regmap, TIM_SMCR, &priv->bak.smcr); in stm32_timer_cnt_suspend()
361 regmap_read(priv->regmap, TIM_ARR, &priv->bak.arr); in stm32_timer_cnt_suspend()
362 regmap_read(priv->regmap, TIM_CNT, &priv->bak.cnt); in stm32_timer_cnt_suspend()
363 regmap_read(priv->regmap, TIM_CR1, &priv->bak.cr1); in stm32_timer_cnt_suspend()
365 /* Disable the counter */ in stm32_timer_cnt_suspend()
366 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); in stm32_timer_cnt_suspend()
367 clk_disable(priv->clk); in stm32_timer_cnt_suspend()
382 if (priv->enabled) { in stm32_timer_cnt_resume()
383 clk_enable(priv->clk); in stm32_timer_cnt_resume()
386 regmap_write(priv->regmap, TIM_SMCR, priv->bak.smcr); in stm32_timer_cnt_resume()
387 regmap_write(priv->regmap, TIM_ARR, priv->bak.arr); in stm32_timer_cnt_resume()
388 regmap_write(priv->regmap, TIM_CNT, priv->bak.cnt); in stm32_timer_cnt_resume()
390 /* Also re-enables the counter */ in stm32_timer_cnt_resume()
391 regmap_write(priv->regmap, TIM_CR1, priv->bak.cr1); in stm32_timer_cnt_resume()
401 { .compatible = "st,stm32-timer-counter", },
409 .name = "stm32-timer-counter",
417 MODULE_ALIAS("platform:stm32-timer-counter");
418 MODULE_DESCRIPTION("STMicroelectronics STM32 TIMER counter driver");
420 MODULE_IMPORT_NS(COUNTER);