1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * This file is part the core part STM32 DFSDM driver 4 * 5 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved 6 * Author(s): Arnaud Pouliquen <arnaud.pouliquen@st.com> for STMicroelectronics. 7 */ 8 9 #include <linux/clk.h> 10 #include <linux/iio/iio.h> 11 #include <linux/iio/sysfs.h> 12 #include <linux/interrupt.h> 13 #include <linux/module.h> 14 #include <linux/of_device.h> 15 #include <linux/pinctrl/consumer.h> 16 #include <linux/pm_runtime.h> 17 #include <linux/regmap.h> 18 #include <linux/slab.h> 19 20 #include "stm32-dfsdm.h" 21 22 struct stm32_dfsdm_dev_data { 23 unsigned int num_filters; 24 unsigned int num_channels; 25 const struct regmap_config *regmap_cfg; 26 }; 27 28 #define STM32H7_DFSDM_NUM_FILTERS 4 29 #define STM32H7_DFSDM_NUM_CHANNELS 8 30 #define STM32MP1_DFSDM_NUM_FILTERS 6 31 #define STM32MP1_DFSDM_NUM_CHANNELS 8 32 33 static bool stm32_dfsdm_volatile_reg(struct device *dev, unsigned int reg) 34 { 35 if (reg < DFSDM_FILTER_BASE_ADR) 36 return false; 37 38 /* 39 * Mask is done on register to avoid to list registers of all 40 * filter instances. 41 */ 42 switch (reg & DFSDM_FILTER_REG_MASK) { 43 case DFSDM_CR1(0) & DFSDM_FILTER_REG_MASK: 44 case DFSDM_ISR(0) & DFSDM_FILTER_REG_MASK: 45 case DFSDM_JDATAR(0) & DFSDM_FILTER_REG_MASK: 46 case DFSDM_RDATAR(0) & DFSDM_FILTER_REG_MASK: 47 return true; 48 } 49 50 return false; 51 } 52 53 static const struct regmap_config stm32h7_dfsdm_regmap_cfg = { 54 .reg_bits = 32, 55 .val_bits = 32, 56 .reg_stride = sizeof(u32), 57 .max_register = 0x2B8, 58 .volatile_reg = stm32_dfsdm_volatile_reg, 59 .fast_io = true, 60 }; 61 62 static const struct stm32_dfsdm_dev_data stm32h7_dfsdm_data = { 63 .num_filters = STM32H7_DFSDM_NUM_FILTERS, 64 .num_channels = STM32H7_DFSDM_NUM_CHANNELS, 65 .regmap_cfg = &stm32h7_dfsdm_regmap_cfg, 66 }; 67 68 static const struct regmap_config stm32mp1_dfsdm_regmap_cfg = { 69 .reg_bits = 32, 70 .val_bits = 32, 71 .reg_stride = sizeof(u32), 72 .max_register = 0x7fc, 73 .volatile_reg = stm32_dfsdm_volatile_reg, 74 .fast_io = true, 75 }; 76 77 static const struct stm32_dfsdm_dev_data stm32mp1_dfsdm_data = { 78 .num_filters = STM32MP1_DFSDM_NUM_FILTERS, 79 .num_channels = STM32MP1_DFSDM_NUM_CHANNELS, 80 .regmap_cfg = &stm32mp1_dfsdm_regmap_cfg, 81 }; 82 83 struct dfsdm_priv { 84 struct platform_device *pdev; /* platform device */ 85 86 struct stm32_dfsdm dfsdm; /* common data exported for all instances */ 87 88 unsigned int spi_clk_out_div; /* SPI clkout divider value */ 89 atomic_t n_active_ch; /* number of current active channels */ 90 91 struct clk *clk; /* DFSDM clock */ 92 struct clk *aclk; /* audio clock */ 93 }; 94 95 static inline struct dfsdm_priv *to_stm32_dfsdm_priv(struct stm32_dfsdm *dfsdm) 96 { 97 return container_of(dfsdm, struct dfsdm_priv, dfsdm); 98 } 99 100 static int stm32_dfsdm_clk_prepare_enable(struct stm32_dfsdm *dfsdm) 101 { 102 struct dfsdm_priv *priv = to_stm32_dfsdm_priv(dfsdm); 103 int ret; 104 105 ret = clk_prepare_enable(priv->clk); 106 if (ret || !priv->aclk) 107 return ret; 108 109 ret = clk_prepare_enable(priv->aclk); 110 if (ret) 111 clk_disable_unprepare(priv->clk); 112 113 return ret; 114 } 115 116 static void stm32_dfsdm_clk_disable_unprepare(struct stm32_dfsdm *dfsdm) 117 { 118 struct dfsdm_priv *priv = to_stm32_dfsdm_priv(dfsdm); 119 120 if (priv->aclk) 121 clk_disable_unprepare(priv->aclk); 122 clk_disable_unprepare(priv->clk); 123 } 124 125 /** 126 * stm32_dfsdm_start_dfsdm - start global dfsdm interface. 127 * 128 * Enable interface if n_active_ch is not null. 129 * @dfsdm: Handle used to retrieve dfsdm context. 130 */ 131 int stm32_dfsdm_start_dfsdm(struct stm32_dfsdm *dfsdm) 132 { 133 struct dfsdm_priv *priv = to_stm32_dfsdm_priv(dfsdm); 134 struct device *dev = &priv->pdev->dev; 135 unsigned int clk_div = priv->spi_clk_out_div, clk_src; 136 int ret; 137 138 if (atomic_inc_return(&priv->n_active_ch) == 1) { 139 ret = pm_runtime_get_sync(dev); 140 if (ret < 0) { 141 pm_runtime_put_noidle(dev); 142 goto error_ret; 143 } 144 145 /* select clock source, e.g. 0 for "dfsdm" or 1 for "audio" */ 146 clk_src = priv->aclk ? 1 : 0; 147 ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0), 148 DFSDM_CHCFGR1_CKOUTSRC_MASK, 149 DFSDM_CHCFGR1_CKOUTSRC(clk_src)); 150 if (ret < 0) 151 goto pm_put; 152 153 /* Output the SPI CLKOUT (if clk_div == 0 clock if OFF) */ 154 ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0), 155 DFSDM_CHCFGR1_CKOUTDIV_MASK, 156 DFSDM_CHCFGR1_CKOUTDIV(clk_div)); 157 if (ret < 0) 158 goto pm_put; 159 160 /* Global enable of DFSDM interface */ 161 ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0), 162 DFSDM_CHCFGR1_DFSDMEN_MASK, 163 DFSDM_CHCFGR1_DFSDMEN(1)); 164 if (ret < 0) 165 goto pm_put; 166 } 167 168 dev_dbg(dev, "%s: n_active_ch %d\n", __func__, 169 atomic_read(&priv->n_active_ch)); 170 171 return 0; 172 173 pm_put: 174 pm_runtime_put_sync(dev); 175 error_ret: 176 atomic_dec(&priv->n_active_ch); 177 178 return ret; 179 } 180 EXPORT_SYMBOL_GPL(stm32_dfsdm_start_dfsdm); 181 182 /** 183 * stm32_dfsdm_stop_dfsdm - stop global DFSDM interface. 184 * 185 * Disable interface if n_active_ch is null 186 * @dfsdm: Handle used to retrieve dfsdm context. 187 */ 188 int stm32_dfsdm_stop_dfsdm(struct stm32_dfsdm *dfsdm) 189 { 190 struct dfsdm_priv *priv = to_stm32_dfsdm_priv(dfsdm); 191 int ret; 192 193 if (atomic_dec_and_test(&priv->n_active_ch)) { 194 /* Global disable of DFSDM interface */ 195 ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0), 196 DFSDM_CHCFGR1_DFSDMEN_MASK, 197 DFSDM_CHCFGR1_DFSDMEN(0)); 198 if (ret < 0) 199 return ret; 200 201 /* Stop SPI CLKOUT */ 202 ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0), 203 DFSDM_CHCFGR1_CKOUTDIV_MASK, 204 DFSDM_CHCFGR1_CKOUTDIV(0)); 205 if (ret < 0) 206 return ret; 207 208 pm_runtime_put_sync(&priv->pdev->dev); 209 } 210 dev_dbg(&priv->pdev->dev, "%s: n_active_ch %d\n", __func__, 211 atomic_read(&priv->n_active_ch)); 212 213 return 0; 214 } 215 EXPORT_SYMBOL_GPL(stm32_dfsdm_stop_dfsdm); 216 217 static int stm32_dfsdm_parse_of(struct platform_device *pdev, 218 struct dfsdm_priv *priv) 219 { 220 struct device_node *node = pdev->dev.of_node; 221 struct resource *res; 222 unsigned long clk_freq, divider; 223 unsigned int spi_freq, rem; 224 int ret; 225 226 if (!node) 227 return -EINVAL; 228 229 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 230 if (!res) { 231 dev_err(&pdev->dev, "Failed to get memory resource\n"); 232 return -ENODEV; 233 } 234 priv->dfsdm.phys_base = res->start; 235 priv->dfsdm.base = devm_ioremap_resource(&pdev->dev, res); 236 if (IS_ERR(priv->dfsdm.base)) 237 return PTR_ERR(priv->dfsdm.base); 238 239 /* 240 * "dfsdm" clock is mandatory for DFSDM peripheral clocking. 241 * "dfsdm" or "audio" clocks can be used as source clock for 242 * the SPI clock out signal and internal processing, depending 243 * on use case. 244 */ 245 priv->clk = devm_clk_get(&pdev->dev, "dfsdm"); 246 if (IS_ERR(priv->clk)) { 247 ret = PTR_ERR(priv->clk); 248 if (ret != -EPROBE_DEFER) 249 dev_err(&pdev->dev, "Failed to get clock (%d)\n", ret); 250 return ret; 251 } 252 253 priv->aclk = devm_clk_get(&pdev->dev, "audio"); 254 if (IS_ERR(priv->aclk)) 255 priv->aclk = NULL; 256 257 if (priv->aclk) 258 clk_freq = clk_get_rate(priv->aclk); 259 else 260 clk_freq = clk_get_rate(priv->clk); 261 262 /* SPI clock out frequency */ 263 ret = of_property_read_u32(pdev->dev.of_node, "spi-max-frequency", 264 &spi_freq); 265 if (ret < 0) { 266 /* No SPI master mode */ 267 return 0; 268 } 269 270 divider = div_u64_rem(clk_freq, spi_freq, &rem); 271 /* Round up divider when ckout isn't precise, not to exceed spi_freq */ 272 if (rem) 273 divider++; 274 275 /* programmable divider is in range of [2:256] */ 276 if (divider < 2 || divider > 256) { 277 dev_err(&pdev->dev, "spi-max-frequency not achievable\n"); 278 return -EINVAL; 279 } 280 281 /* SPI clock output divider is: divider = CKOUTDIV + 1 */ 282 priv->spi_clk_out_div = divider - 1; 283 priv->dfsdm.spi_master_freq = clk_freq / (priv->spi_clk_out_div + 1); 284 285 if (rem) { 286 dev_warn(&pdev->dev, "SPI clock not accurate\n"); 287 dev_warn(&pdev->dev, "%ld = %d * %d + %d\n", 288 clk_freq, spi_freq, priv->spi_clk_out_div + 1, rem); 289 } 290 291 return 0; 292 }; 293 294 static const struct of_device_id stm32_dfsdm_of_match[] = { 295 { 296 .compatible = "st,stm32h7-dfsdm", 297 .data = &stm32h7_dfsdm_data, 298 }, 299 { 300 .compatible = "st,stm32mp1-dfsdm", 301 .data = &stm32mp1_dfsdm_data, 302 }, 303 {} 304 }; 305 MODULE_DEVICE_TABLE(of, stm32_dfsdm_of_match); 306 307 static int stm32_dfsdm_probe(struct platform_device *pdev) 308 { 309 struct dfsdm_priv *priv; 310 const struct stm32_dfsdm_dev_data *dev_data; 311 struct stm32_dfsdm *dfsdm; 312 int ret; 313 314 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 315 if (!priv) 316 return -ENOMEM; 317 318 priv->pdev = pdev; 319 320 dev_data = of_device_get_match_data(&pdev->dev); 321 322 dfsdm = &priv->dfsdm; 323 dfsdm->fl_list = devm_kcalloc(&pdev->dev, dev_data->num_filters, 324 sizeof(*dfsdm->fl_list), GFP_KERNEL); 325 if (!dfsdm->fl_list) 326 return -ENOMEM; 327 328 dfsdm->num_fls = dev_data->num_filters; 329 dfsdm->ch_list = devm_kcalloc(&pdev->dev, dev_data->num_channels, 330 sizeof(*dfsdm->ch_list), 331 GFP_KERNEL); 332 if (!dfsdm->ch_list) 333 return -ENOMEM; 334 dfsdm->num_chs = dev_data->num_channels; 335 336 ret = stm32_dfsdm_parse_of(pdev, priv); 337 if (ret < 0) 338 return ret; 339 340 dfsdm->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "dfsdm", 341 dfsdm->base, 342 dev_data->regmap_cfg); 343 if (IS_ERR(dfsdm->regmap)) { 344 ret = PTR_ERR(dfsdm->regmap); 345 dev_err(&pdev->dev, "%s: Failed to allocate regmap: %d\n", 346 __func__, ret); 347 return ret; 348 } 349 350 platform_set_drvdata(pdev, dfsdm); 351 352 ret = stm32_dfsdm_clk_prepare_enable(dfsdm); 353 if (ret) { 354 dev_err(&pdev->dev, "Failed to start clock\n"); 355 return ret; 356 } 357 358 pm_runtime_get_noresume(&pdev->dev); 359 pm_runtime_set_active(&pdev->dev); 360 pm_runtime_enable(&pdev->dev); 361 362 ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); 363 if (ret) 364 goto pm_put; 365 366 pm_runtime_put(&pdev->dev); 367 368 return 0; 369 370 pm_put: 371 pm_runtime_disable(&pdev->dev); 372 pm_runtime_set_suspended(&pdev->dev); 373 pm_runtime_put_noidle(&pdev->dev); 374 stm32_dfsdm_clk_disable_unprepare(dfsdm); 375 376 return ret; 377 } 378 379 static int stm32_dfsdm_core_remove(struct platform_device *pdev) 380 { 381 struct stm32_dfsdm *dfsdm = platform_get_drvdata(pdev); 382 383 pm_runtime_get_sync(&pdev->dev); 384 of_platform_depopulate(&pdev->dev); 385 pm_runtime_disable(&pdev->dev); 386 pm_runtime_set_suspended(&pdev->dev); 387 pm_runtime_put_noidle(&pdev->dev); 388 stm32_dfsdm_clk_disable_unprepare(dfsdm); 389 390 return 0; 391 } 392 393 static int __maybe_unused stm32_dfsdm_core_suspend(struct device *dev) 394 { 395 struct stm32_dfsdm *dfsdm = dev_get_drvdata(dev); 396 struct dfsdm_priv *priv = to_stm32_dfsdm_priv(dfsdm); 397 int ret; 398 399 ret = pm_runtime_force_suspend(dev); 400 if (ret) 401 return ret; 402 403 /* Balance devm_regmap_init_mmio_clk() clk_prepare() */ 404 clk_unprepare(priv->clk); 405 406 return pinctrl_pm_select_sleep_state(dev); 407 } 408 409 static int __maybe_unused stm32_dfsdm_core_resume(struct device *dev) 410 { 411 struct stm32_dfsdm *dfsdm = dev_get_drvdata(dev); 412 struct dfsdm_priv *priv = to_stm32_dfsdm_priv(dfsdm); 413 int ret; 414 415 ret = pinctrl_pm_select_default_state(dev); 416 if (ret) 417 return ret; 418 419 ret = clk_prepare(priv->clk); 420 if (ret) 421 return ret; 422 423 return pm_runtime_force_resume(dev); 424 } 425 426 static int __maybe_unused stm32_dfsdm_core_runtime_suspend(struct device *dev) 427 { 428 struct stm32_dfsdm *dfsdm = dev_get_drvdata(dev); 429 430 stm32_dfsdm_clk_disable_unprepare(dfsdm); 431 432 return 0; 433 } 434 435 static int __maybe_unused stm32_dfsdm_core_runtime_resume(struct device *dev) 436 { 437 struct stm32_dfsdm *dfsdm = dev_get_drvdata(dev); 438 439 return stm32_dfsdm_clk_prepare_enable(dfsdm); 440 } 441 442 static const struct dev_pm_ops stm32_dfsdm_core_pm_ops = { 443 SET_SYSTEM_SLEEP_PM_OPS(stm32_dfsdm_core_suspend, 444 stm32_dfsdm_core_resume) 445 SET_RUNTIME_PM_OPS(stm32_dfsdm_core_runtime_suspend, 446 stm32_dfsdm_core_runtime_resume, 447 NULL) 448 }; 449 450 static struct platform_driver stm32_dfsdm_driver = { 451 .probe = stm32_dfsdm_probe, 452 .remove = stm32_dfsdm_core_remove, 453 .driver = { 454 .name = "stm32-dfsdm", 455 .of_match_table = stm32_dfsdm_of_match, 456 .pm = &stm32_dfsdm_core_pm_ops, 457 }, 458 }; 459 460 module_platform_driver(stm32_dfsdm_driver); 461 462 MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>"); 463 MODULE_DESCRIPTION("STMicroelectronics STM32 dfsdm driver"); 464 MODULE_LICENSE("GPL v2"); 465