#include <linux/counter.h>
#include <linux/interrupt.h>
#include <linux/mfd/stm32-timers.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#define TIM_CCMR_CCXS …
#define TIM_CCMR_MASK …
#define TIM_CCER_MASK …
#define STM32_CH1_SIG …
#define STM32_CH2_SIG …
#define STM32_CLOCK_SIG …
#define STM32_CH3_SIG …
#define STM32_CH4_SIG …
struct stm32_timer_regs { … };
struct stm32_timer_cnt { … };
static const enum counter_function stm32_count_functions[] = …;
static int stm32_count_read(struct counter_device *counter,
struct counter_count *count, u64 *val)
{ … }
static int stm32_count_write(struct counter_device *counter,
struct counter_count *count, const u64 val)
{ … }
static int stm32_count_function_read(struct counter_device *counter,
struct counter_count *count,
enum counter_function *function)
{ … }
static int stm32_count_function_write(struct counter_device *counter,
struct counter_count *count,
enum counter_function function)
{ … }
static int stm32_count_direction_read(struct counter_device *counter,
struct counter_count *count,
enum counter_count_direction *direction)
{ … }
static int stm32_count_ceiling_read(struct counter_device *counter,
struct counter_count *count, u64 *ceiling)
{ … }
static int stm32_count_ceiling_write(struct counter_device *counter,
struct counter_count *count, u64 ceiling)
{ … }
static int stm32_count_enable_read(struct counter_device *counter,
struct counter_count *count, u8 *enable)
{ … }
static int stm32_count_enable_write(struct counter_device *counter,
struct counter_count *count, u8 enable)
{ … }
static int stm32_count_prescaler_read(struct counter_device *counter,
struct counter_count *count, u64 *prescaler)
{ … }
static int stm32_count_prescaler_write(struct counter_device *counter,
struct counter_count *count, u64 prescaler)
{ … }
static int stm32_count_cap_read(struct counter_device *counter,
struct counter_count *count,
size_t ch, u64 *cap)
{ … }
static int stm32_count_nb_ovf_read(struct counter_device *counter,
struct counter_count *count, u64 *val)
{ … }
static int stm32_count_nb_ovf_write(struct counter_device *counter,
struct counter_count *count, u64 val)
{ … }
static DEFINE_COUNTER_ARRAY_CAPTURE(stm32_count_cap_array, 4);
static struct counter_comp stm32_count_ext[] = …;
static const enum counter_synapse_action stm32_clock_synapse_actions[] = …;
static const enum counter_synapse_action stm32_synapse_actions[] = …;
static int stm32_action_read(struct counter_device *counter,
struct counter_count *count,
struct counter_synapse *synapse,
enum counter_synapse_action *action)
{ … }
struct stm32_count_cc_regs { … };
static const struct stm32_count_cc_regs stm32_cc[] = …;
static int stm32_count_capture_configure(struct counter_device *counter, unsigned int ch,
bool enable)
{ … }
static int stm32_count_events_configure(struct counter_device *counter)
{ … }
static int stm32_count_watch_validate(struct counter_device *counter,
const struct counter_watch *watch)
{ … }
static const struct counter_ops stm32_timer_cnt_ops = …;
static int stm32_count_clk_get_freq(struct counter_device *counter,
struct counter_signal *signal, u64 *freq)
{ … }
static struct counter_comp stm32_count_clock_ext[] = …;
static struct counter_signal stm32_signals[] = …;
static struct counter_synapse stm32_count_synapses[] = …;
static struct counter_count stm32_counts = …;
static irqreturn_t stm32_timer_cnt_isr(int irq, void *ptr)
{
struct counter_device *counter = ptr;
struct stm32_timer_cnt *const priv = counter_priv(counter);
u32 clr = GENMASK(31, 0);
u32 sr, dier;
int i;
regmap_read(priv->regmap, TIM_SR, &sr);
regmap_read(priv->regmap, TIM_DIER, &dier);
dier &= (TIM_DIER_UIE | TIM_DIER_CC1IE | TIM_DIER_CC2IE | TIM_DIER_CC3IE | TIM_DIER_CC4IE);
sr &= dier;
if (sr & TIM_SR_UIF) {
spin_lock(&priv->lock);
priv->nb_ovf++;
spin_unlock(&priv->lock);
counter_push_event(counter, COUNTER_EVENT_OVERFLOW_UNDERFLOW, 0);
dev_dbg(counter->parent, "COUNTER_EVENT_OVERFLOW_UNDERFLOW\n");
clr &= ~TIM_SR_UIF;
}
for (i = 0 ; i < priv->nchannels; i++) {
if (sr & TIM_SR_CC_IF(i)) {
counter_push_event(counter, COUNTER_EVENT_CAPTURE, i);
clr &= ~TIM_SR_CC_IF(i);
dev_dbg(counter->parent, "COUNTER_EVENT_CAPTURE, %d\n", i);
}
}
regmap_write(priv->regmap, TIM_SR, clr);
return IRQ_HANDLED;
};
static void stm32_timer_cnt_detect_channels(struct device *dev,
struct stm32_timer_cnt *priv)
{ … }
#define STM32_TIM_ENCODER_SUPPORTED …
static const char * const stm32_timer_trigger_compat[] = …;
static int stm32_timer_cnt_probe_encoder(struct device *dev,
struct stm32_timer_cnt *priv)
{ … }
static int stm32_timer_cnt_probe(struct platform_device *pdev)
{ … }
static int __maybe_unused stm32_timer_cnt_suspend(struct device *dev)
{ … }
static int __maybe_unused stm32_timer_cnt_resume(struct device *dev)
{ … }
static SIMPLE_DEV_PM_OPS(stm32_timer_cnt_pm_ops, stm32_timer_cnt_suspend,
stm32_timer_cnt_resume);
static const struct of_device_id stm32_timer_cnt_of_match[] = …;
MODULE_DEVICE_TABLE(of, stm32_timer_cnt_of_match);
static struct platform_driver stm32_timer_cnt_driver = …;
module_platform_driver(…) …;
MODULE_AUTHOR(…) …;
MODULE_ALIAS(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;
MODULE_IMPORT_NS(…);