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