File Index
Files and directories
Sign in
FILE

stm32-lptimer-trigger.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/trigger/stm32-lptimer-trigger.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * STM32 Low-Power Timer Trigger driver
  4 *
  5 * Copyright (C) STMicroelectronics 2017
  6 *
  7 * Author: Fabrice Gasnier <fabrice.gasnier@st.com>.
  8 *
  9 * Inspired by Benjamin Gaignard's stm32-timer-trigger driver
 10 */
 11
 12#include <linux/export.h>
 13#include <linux/iio/timer/stm32-lptim-trigger.h>
 14#include <linux/mfd/stm32-lptimer.h>
 15#include <linux/mod_devicetable.h>
 16#include <linux/module.h>
 17#include <linux/platform_device.h>
 18#include <linux/property.h>
 19
 20/* Maximum triggers + one trailing null entry to indicate the end of array */
 21#define MAX_TRIGGERS 3
 22
 23struct stm32_lptim_cfg {
 24	const char * const (*triggers)[MAX_TRIGGERS];
 25	unsigned int nb_triggers;
 26};
 27
 28/* List Low-Power Timer triggers for H7, MP13, MP15 */
 29static const char * const stm32_lptim_triggers[][MAX_TRIGGERS] = {
 30	{ LPTIM1_OUT,},
 31	{ LPTIM2_OUT,},
 32	{ LPTIM3_OUT,},
 33};
 34
 35/* List Low-Power Timer triggers for STM32MP25 */
 36static const char * const stm32mp25_lptim_triggers[][MAX_TRIGGERS] = {
 37	{ LPTIM1_CH1, LPTIM1_CH2, },
 38	{ LPTIM2_CH1, LPTIM2_CH2, },
 39	{ LPTIM3_CH1,},
 40	{ LPTIM4_CH1,},
 41	{ LPTIM5_OUT,},
 42};
 43
 44static const struct stm32_lptim_cfg stm32mp15_lptim_cfg = {
 45	.triggers = stm32_lptim_triggers,
 46	.nb_triggers = ARRAY_SIZE(stm32_lptim_triggers),
 47};
 48
 49static const struct stm32_lptim_cfg stm32mp25_lptim_cfg = {
 50	.triggers = stm32mp25_lptim_triggers,
 51	.nb_triggers = ARRAY_SIZE(stm32mp25_lptim_triggers),
 52};
 53
 54struct stm32_lptim_trigger {
 55	struct device *dev;
 56	const char * const *triggers;
 57};
 58
 59static int stm32_lptim_validate_device(struct iio_trigger *trig,
 60				       struct iio_dev *indio_dev)
 61{
 62	if (indio_dev->modes & INDIO_HARDWARE_TRIGGERED)
 63		return 0;
 64
 65	return -EINVAL;
 66}
 67
 68static const struct iio_trigger_ops stm32_lptim_trigger_ops = {
 69	.validate_device = stm32_lptim_validate_device,
 70};
 71
 72/**
 73 * is_stm32_lptim_trigger
 74 * @trig: trigger to be checked
 75 *
 76 * return true if the trigger is a valid STM32 IIO Low-Power Timer Trigger
 77 * either return false
 78 */
 79bool is_stm32_lptim_trigger(struct iio_trigger *trig)
 80{
 81	return (trig->ops == &stm32_lptim_trigger_ops);
 82}
 83EXPORT_SYMBOL(is_stm32_lptim_trigger);
 84
 85static int stm32_lptim_setup_trig(struct stm32_lptim_trigger *priv)
 86{
 87	const char * const *cur = priv->triggers;
 88	int ret;
 89
 90	while (cur && *cur) {
 91		struct iio_trigger *trig;
 92
 93		trig = devm_iio_trigger_alloc(priv->dev, "%s", *cur);
 94		if  (!trig)
 95			return -ENOMEM;
 96
 97		trig->dev.parent = priv->dev->parent;
 98		trig->ops = &stm32_lptim_trigger_ops;
 99		iio_trigger_set_drvdata(trig, priv);
100
101		ret = devm_iio_trigger_register(priv->dev, trig);
102		if (ret)
103			return ret;
104		cur++;
105	}
106
107	return 0;
108}
109
110static int stm32_lptim_trigger_probe(struct platform_device *pdev)
111{
112	struct stm32_lptim_trigger *priv;
113	struct stm32_lptim_cfg const *lptim_cfg;
114	u32 index;
115
116	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
117	if (!priv)
118		return -ENOMEM;
119
120	if (device_property_read_u32(&pdev->dev, "reg", &index))
121		return -EINVAL;
122
123	lptim_cfg = device_get_match_data(&pdev->dev);
124
125	if (index >= lptim_cfg->nb_triggers)
126		return -EINVAL;
127
128	priv->dev = &pdev->dev;
129	priv->triggers = lptim_cfg->triggers[index];
130
131	return stm32_lptim_setup_trig(priv);
132}
133
134static const struct of_device_id stm32_lptim_trig_of_match[] = {
135	{ .compatible = "st,stm32-lptimer-trigger", .data = &stm32mp15_lptim_cfg },
136	{ .compatible = "st,stm32mp25-lptimer-trigger", .data = &stm32mp25_lptim_cfg},
137	{ }
138};
139MODULE_DEVICE_TABLE(of, stm32_lptim_trig_of_match);
140
141static struct platform_driver stm32_lptim_trigger_driver = {
142	.probe = stm32_lptim_trigger_probe,
143	.driver = {
144		.name = "stm32-lptimer-trigger",
145		.of_match_table = stm32_lptim_trig_of_match,
146	},
147};
148module_platform_driver(stm32_lptim_trigger_driver);
149
150MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");
151MODULE_ALIAS("platform:stm32-lptimer-trigger");
152MODULE_DESCRIPTION("STMicroelectronics STM32 LPTIM trigger driver");
153MODULE_LICENSE("GPL v2");
~/ Read-only file preview.