1b01ced2bSFabrice Gasnier /* 2b01ced2bSFabrice Gasnier * STM32 Low-Power Timer Trigger driver 3b01ced2bSFabrice Gasnier * 4b01ced2bSFabrice Gasnier * Copyright (C) STMicroelectronics 2017 5b01ced2bSFabrice Gasnier * 6b01ced2bSFabrice Gasnier * Author: Fabrice Gasnier <fabrice.gasnier@st.com>. 7b01ced2bSFabrice Gasnier * 8b01ced2bSFabrice Gasnier * License terms: GNU General Public License (GPL), version 2 9b01ced2bSFabrice Gasnier * 10b01ced2bSFabrice Gasnier * Inspired by Benjamin Gaignard's stm32-timer-trigger driver 11b01ced2bSFabrice Gasnier */ 12b01ced2bSFabrice Gasnier 13b01ced2bSFabrice Gasnier #include <linux/iio/timer/stm32-lptim-trigger.h> 14b01ced2bSFabrice Gasnier #include <linux/mfd/stm32-lptimer.h> 15b01ced2bSFabrice Gasnier #include <linux/module.h> 16b01ced2bSFabrice Gasnier #include <linux/platform_device.h> 17b01ced2bSFabrice Gasnier 18b01ced2bSFabrice Gasnier /* List Low-Power Timer triggers */ 19b01ced2bSFabrice Gasnier static const char * const stm32_lptim_triggers[] = { 20b01ced2bSFabrice Gasnier LPTIM1_OUT, 21b01ced2bSFabrice Gasnier LPTIM2_OUT, 22b01ced2bSFabrice Gasnier LPTIM3_OUT, 23b01ced2bSFabrice Gasnier }; 24b01ced2bSFabrice Gasnier 25b01ced2bSFabrice Gasnier struct stm32_lptim_trigger { 26b01ced2bSFabrice Gasnier struct device *dev; 27b01ced2bSFabrice Gasnier const char *trg; 28b01ced2bSFabrice Gasnier }; 29b01ced2bSFabrice Gasnier 30b01ced2bSFabrice Gasnier static int stm32_lptim_validate_device(struct iio_trigger *trig, 31b01ced2bSFabrice Gasnier struct iio_dev *indio_dev) 32b01ced2bSFabrice Gasnier { 33b01ced2bSFabrice Gasnier if (indio_dev->modes & INDIO_HARDWARE_TRIGGERED) 34b01ced2bSFabrice Gasnier return 0; 35b01ced2bSFabrice Gasnier 36b01ced2bSFabrice Gasnier return -EINVAL; 37b01ced2bSFabrice Gasnier } 38b01ced2bSFabrice Gasnier 39b01ced2bSFabrice Gasnier static const struct iio_trigger_ops stm32_lptim_trigger_ops = { 40b01ced2bSFabrice Gasnier .owner = THIS_MODULE, 41b01ced2bSFabrice Gasnier .validate_device = stm32_lptim_validate_device, 42b01ced2bSFabrice Gasnier }; 43b01ced2bSFabrice Gasnier 44b01ced2bSFabrice Gasnier /** 45b01ced2bSFabrice Gasnier * is_stm32_lptim_trigger 46b01ced2bSFabrice Gasnier * @trig: trigger to be checked 47b01ced2bSFabrice Gasnier * 48b01ced2bSFabrice Gasnier * return true if the trigger is a valid STM32 IIO Low-Power Timer Trigger 49b01ced2bSFabrice Gasnier * either return false 50b01ced2bSFabrice Gasnier */ 51b01ced2bSFabrice Gasnier bool is_stm32_lptim_trigger(struct iio_trigger *trig) 52b01ced2bSFabrice Gasnier { 53b01ced2bSFabrice Gasnier return (trig->ops == &stm32_lptim_trigger_ops); 54b01ced2bSFabrice Gasnier } 55b01ced2bSFabrice Gasnier EXPORT_SYMBOL(is_stm32_lptim_trigger); 56b01ced2bSFabrice Gasnier 57b01ced2bSFabrice Gasnier static int stm32_lptim_setup_trig(struct stm32_lptim_trigger *priv) 58b01ced2bSFabrice Gasnier { 59b01ced2bSFabrice Gasnier struct iio_trigger *trig; 60b01ced2bSFabrice Gasnier 61b01ced2bSFabrice Gasnier trig = devm_iio_trigger_alloc(priv->dev, "%s", priv->trg); 62b01ced2bSFabrice Gasnier if (!trig) 63b01ced2bSFabrice Gasnier return -ENOMEM; 64b01ced2bSFabrice Gasnier 65b01ced2bSFabrice Gasnier trig->dev.parent = priv->dev->parent; 66b01ced2bSFabrice Gasnier trig->ops = &stm32_lptim_trigger_ops; 67b01ced2bSFabrice Gasnier iio_trigger_set_drvdata(trig, priv); 68b01ced2bSFabrice Gasnier 69b01ced2bSFabrice Gasnier return devm_iio_trigger_register(priv->dev, trig); 70b01ced2bSFabrice Gasnier } 71b01ced2bSFabrice Gasnier 72b01ced2bSFabrice Gasnier static int stm32_lptim_trigger_probe(struct platform_device *pdev) 73b01ced2bSFabrice Gasnier { 74b01ced2bSFabrice Gasnier struct stm32_lptim_trigger *priv; 75b01ced2bSFabrice Gasnier u32 index; 76b01ced2bSFabrice Gasnier int ret; 77b01ced2bSFabrice Gasnier 78b01ced2bSFabrice Gasnier priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 79b01ced2bSFabrice Gasnier if (!priv) 80b01ced2bSFabrice Gasnier return -ENOMEM; 81b01ced2bSFabrice Gasnier 82b01ced2bSFabrice Gasnier if (of_property_read_u32(pdev->dev.of_node, "reg", &index)) 83b01ced2bSFabrice Gasnier return -EINVAL; 84b01ced2bSFabrice Gasnier 85b01ced2bSFabrice Gasnier if (index >= ARRAY_SIZE(stm32_lptim_triggers)) 86b01ced2bSFabrice Gasnier return -EINVAL; 87b01ced2bSFabrice Gasnier 88b01ced2bSFabrice Gasnier priv->dev = &pdev->dev; 89b01ced2bSFabrice Gasnier priv->trg = stm32_lptim_triggers[index]; 90b01ced2bSFabrice Gasnier 91b01ced2bSFabrice Gasnier ret = stm32_lptim_setup_trig(priv); 92b01ced2bSFabrice Gasnier if (ret) 93b01ced2bSFabrice Gasnier return ret; 94b01ced2bSFabrice Gasnier 95b01ced2bSFabrice Gasnier platform_set_drvdata(pdev, priv); 96b01ced2bSFabrice Gasnier 97b01ced2bSFabrice Gasnier return 0; 98b01ced2bSFabrice Gasnier } 99b01ced2bSFabrice Gasnier 100b01ced2bSFabrice Gasnier static const struct of_device_id stm32_lptim_trig_of_match[] = { 101b01ced2bSFabrice Gasnier { .compatible = "st,stm32-lptimer-trigger", }, 102b01ced2bSFabrice Gasnier {}, 103b01ced2bSFabrice Gasnier }; 104b01ced2bSFabrice Gasnier MODULE_DEVICE_TABLE(of, stm32_lptim_trig_of_match); 105b01ced2bSFabrice Gasnier 106b01ced2bSFabrice Gasnier static struct platform_driver stm32_lptim_trigger_driver = { 107b01ced2bSFabrice Gasnier .probe = stm32_lptim_trigger_probe, 108b01ced2bSFabrice Gasnier .driver = { 109b01ced2bSFabrice Gasnier .name = "stm32-lptimer-trigger", 110b01ced2bSFabrice Gasnier .of_match_table = stm32_lptim_trig_of_match, 111b01ced2bSFabrice Gasnier }, 112b01ced2bSFabrice Gasnier }; 113b01ced2bSFabrice Gasnier module_platform_driver(stm32_lptim_trigger_driver); 114b01ced2bSFabrice Gasnier 115b01ced2bSFabrice Gasnier MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>"); 116b01ced2bSFabrice Gasnier MODULE_ALIAS("platform:stm32-lptimer-trigger"); 117b01ced2bSFabrice Gasnier MODULE_DESCRIPTION("STMicroelectronics STM32 LPTIM trigger driver"); 118b01ced2bSFabrice Gasnier MODULE_LICENSE("GPL v2"); 119