0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/mfd/stm32-lptimer.h>
0010 #include <linux/module.h>
0011 #include <linux/of_platform.h>
0012
0013 #define STM32_LPTIM_MAX_REGISTER 0x3fc
0014
0015 static const struct regmap_config stm32_lptimer_regmap_cfg = {
0016 .reg_bits = 32,
0017 .val_bits = 32,
0018 .reg_stride = sizeof(u32),
0019 .max_register = STM32_LPTIM_MAX_REGISTER,
0020 .fast_io = true,
0021 };
0022
0023 static int stm32_lptimer_detect_encoder(struct stm32_lptimer *ddata)
0024 {
0025 u32 val;
0026 int ret;
0027
0028
0029
0030
0031
0032 ret = regmap_update_bits(ddata->regmap, STM32_LPTIM_CFGR,
0033 STM32_LPTIM_ENC, STM32_LPTIM_ENC);
0034 if (ret)
0035 return ret;
0036
0037 ret = regmap_read(ddata->regmap, STM32_LPTIM_CFGR, &val);
0038 if (ret)
0039 return ret;
0040
0041 ret = regmap_update_bits(ddata->regmap, STM32_LPTIM_CFGR,
0042 STM32_LPTIM_ENC, 0);
0043 if (ret)
0044 return ret;
0045
0046 ddata->has_encoder = !!(val & STM32_LPTIM_ENC);
0047
0048 return 0;
0049 }
0050
0051 static int stm32_lptimer_probe(struct platform_device *pdev)
0052 {
0053 struct device *dev = &pdev->dev;
0054 struct stm32_lptimer *ddata;
0055 struct resource *res;
0056 void __iomem *mmio;
0057 int ret;
0058
0059 ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
0060 if (!ddata)
0061 return -ENOMEM;
0062
0063 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0064 mmio = devm_ioremap_resource(dev, res);
0065 if (IS_ERR(mmio))
0066 return PTR_ERR(mmio);
0067
0068 ddata->regmap = devm_regmap_init_mmio_clk(dev, "mux", mmio,
0069 &stm32_lptimer_regmap_cfg);
0070 if (IS_ERR(ddata->regmap))
0071 return PTR_ERR(ddata->regmap);
0072
0073 ddata->clk = devm_clk_get(dev, NULL);
0074 if (IS_ERR(ddata->clk))
0075 return PTR_ERR(ddata->clk);
0076
0077 ret = stm32_lptimer_detect_encoder(ddata);
0078 if (ret)
0079 return ret;
0080
0081 platform_set_drvdata(pdev, ddata);
0082
0083 return devm_of_platform_populate(&pdev->dev);
0084 }
0085
0086 static const struct of_device_id stm32_lptimer_of_match[] = {
0087 { .compatible = "st,stm32-lptimer", },
0088 {},
0089 };
0090 MODULE_DEVICE_TABLE(of, stm32_lptimer_of_match);
0091
0092 static struct platform_driver stm32_lptimer_driver = {
0093 .probe = stm32_lptimer_probe,
0094 .driver = {
0095 .name = "stm32-lptimer",
0096 .of_match_table = stm32_lptimer_of_match,
0097 },
0098 };
0099 module_platform_driver(stm32_lptimer_driver);
0100
0101 MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");
0102 MODULE_DESCRIPTION("STMicroelectronics STM32 Low-Power Timer");
0103 MODULE_ALIAS("platform:stm32-lptimer");
0104 MODULE_LICENSE("GPL v2");