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