104 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * STM32 Low-Power Timer parent driver.4 * Copyright (C) STMicroelectronics 20175 * Author: Fabrice Gasnier <fabrice.gasnier@st.com>6 * Inspired by Benjamin Gaignard's stm32-timers driver7 */8 9#include <linux/mfd/stm32-lptimer.h>10#include <linux/module.h>11#include <linux/of_platform.h>12#include <linux/platform_device.h>13 14#define STM32_LPTIM_MAX_REGISTER 0x3fc15 16static const struct regmap_config stm32_lptimer_regmap_cfg = {17 .reg_bits = 32,18 .val_bits = 32,19 .reg_stride = sizeof(u32),20 .max_register = STM32_LPTIM_MAX_REGISTER,21 .fast_io = true,22};23 24static int stm32_lptimer_detect_encoder(struct stm32_lptimer *ddata)25{26 u32 val;27 int ret;28 29 /*30 * Quadrature encoder mode bit can only be written and read back when31 * Low-Power Timer supports it.32 */33 ret = regmap_update_bits(ddata->regmap, STM32_LPTIM_CFGR,34 STM32_LPTIM_ENC, STM32_LPTIM_ENC);35 if (ret)36 return ret;37 38 ret = regmap_read(ddata->regmap, STM32_LPTIM_CFGR, &val);39 if (ret)40 return ret;41 42 ret = regmap_update_bits(ddata->regmap, STM32_LPTIM_CFGR,43 STM32_LPTIM_ENC, 0);44 if (ret)45 return ret;46 47 ddata->has_encoder = !!(val & STM32_LPTIM_ENC);48 49 return 0;50}51 52static int stm32_lptimer_probe(struct platform_device *pdev)53{54 struct device *dev = &pdev->dev;55 struct stm32_lptimer *ddata;56 void __iomem *mmio;57 int ret;58 59 ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);60 if (!ddata)61 return -ENOMEM;62 63 mmio = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);64 if (IS_ERR(mmio))65 return PTR_ERR(mmio);66 67 ddata->regmap = devm_regmap_init_mmio_clk(dev, "mux", mmio,68 &stm32_lptimer_regmap_cfg);69 if (IS_ERR(ddata->regmap))70 return PTR_ERR(ddata->regmap);71 72 ddata->clk = devm_clk_get(dev, NULL);73 if (IS_ERR(ddata->clk))74 return PTR_ERR(ddata->clk);75 76 ret = stm32_lptimer_detect_encoder(ddata);77 if (ret)78 return ret;79 80 platform_set_drvdata(pdev, ddata);81 82 return devm_of_platform_populate(&pdev->dev);83}84 85static const struct of_device_id stm32_lptimer_of_match[] = {86 { .compatible = "st,stm32-lptimer", },87 {},88};89MODULE_DEVICE_TABLE(of, stm32_lptimer_of_match);90 91static struct platform_driver stm32_lptimer_driver = {92 .probe = stm32_lptimer_probe,93 .driver = {94 .name = "stm32-lptimer",95 .of_match_table = stm32_lptimer_of_match,96 },97};98module_platform_driver(stm32_lptimer_driver);99 100MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");101MODULE_DESCRIPTION("STMicroelectronics STM32 Low-Power Timer");102MODULE_ALIAS("platform:stm32-lptimer");103MODULE_LICENSE("GPL v2");104