Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: stm32: i2s: add stm32mp25 support

Merge series from Olivier Moysan <olivier.moysan@foss.st.com>:

Update STM32 I2S driver and binding to support STM32MP25 SoCs.

+222 -25
+33 -3
Documentation/devicetree/bindings/sound/st,stm32-i2s.yaml
··· 13 13 The SPI/I2S block supports I2S/PCM protocols when configured on I2S mode. 14 14 Only some SPI instances support I2S. 15 15 16 - allOf: 17 - - $ref: dai-common.yaml# 18 - 19 16 properties: 20 17 compatible: 21 18 enum: 22 19 - st,stm32h7-i2s 20 + - st,stm32mp25-i2s 23 21 24 22 "#sound-dai-cells": 25 23 const: 0 ··· 31 33 - description: clock feeding the internal clock generator. 32 34 - description: I2S parent clock for sampling rates multiple of 8kHz. 33 35 - description: I2S parent clock for sampling rates multiple of 11.025kHz. 36 + minItems: 2 34 37 35 38 clock-names: 36 39 items: ··· 39 40 - const: i2sclk 40 41 - const: x8k 41 42 - const: x11k 43 + minItems: 2 42 44 43 45 interrupts: 44 46 maxItems: 1 ··· 78 78 - interrupts 79 79 - dmas 80 80 - dma-names 81 + 82 + allOf: 83 + - $ref: dai-common.yaml# 84 + - if: 85 + properties: 86 + compatible: 87 + contains: 88 + const: st,stm32h7-i2s 89 + 90 + then: 91 + properties: 92 + clocks: 93 + minItems: 4 94 + 95 + clock-names: 96 + minItems: 4 97 + 98 + - if: 99 + properties: 100 + compatible: 101 + contains: 102 + const: st,stm32mp25-i2s 103 + 104 + then: 105 + properties: 106 + clocks: 107 + maxItems: 2 108 + 109 + clock-names: 110 + maxItems: 2 81 111 82 112 unevaluatedProperties: false 83 113
+189 -22
sound/soc/stm/stm32_i2s.c
··· 200 200 201 201 #define STM32_I2S_NAME_LEN 32 202 202 #define STM32_I2S_RATE_11K 11025 203 + #define STM32_I2S_MAX_SAMPLE_RATE_8K 192000 204 + #define STM32_I2S_MAX_SAMPLE_RATE_11K 176400 205 + #define STM32_I2S_CLK_RATE_TOLERANCE 1000 /* ppm */ 203 206 204 207 /** 205 208 * struct stm32_i2s_data - private data of I2S 206 - * @regmap_conf: I2S register map configuration pointer 209 + * @conf: I2S configuration pointer 207 210 * @regmap: I2S register map pointer 208 211 * @pdev: device data pointer 209 212 * @dai_drv: DAI driver pointer ··· 227 224 * @divider: prescaler division ratio 228 225 * @div: prescaler div field 229 226 * @odd: prescaler odd field 227 + * @i2s_clk_flg: flag set while exclusivity on I2S kernel clock is active 230 228 * @refcount: keep count of opened streams on I2S 231 229 * @ms_flg: master mode flag. 230 + * @set_i2s_clk_rate: set I2S kernel clock rate 231 + * @put_i2s_clk_rate: put I2S kernel clock rate 232 232 */ 233 233 struct stm32_i2s_data { 234 - const struct regmap_config *regmap_conf; 234 + const struct stm32_i2s_conf *conf; 235 235 struct regmap *regmap; 236 236 struct platform_device *pdev; 237 237 struct snd_soc_dai_driver *dai_drv; ··· 255 249 unsigned int divider; 256 250 unsigned int div; 257 251 bool odd; 252 + bool i2s_clk_flg; 258 253 int refcount; 259 254 int ms_flg; 255 + int (*set_i2s_clk_rate)(struct stm32_i2s_data *i2s, unsigned int rate); 256 + void (*put_i2s_clk_rate)(struct stm32_i2s_data *i2s); 257 + }; 258 + 259 + /** 260 + * struct stm32_i2s_conf - I2S configuration 261 + * @regmap_conf: regmap configuration pointer 262 + * @get_i2s_clk_parent: get parent clock of I2S kernel clock 263 + */ 264 + struct stm32_i2s_conf { 265 + const struct regmap_config *regmap_conf; 266 + int (*get_i2s_clk_parent)(struct stm32_i2s_data *i2s); 260 267 }; 261 268 262 269 struct stm32_i2smclk_data { ··· 279 260 }; 280 261 281 262 #define to_mclk_data(_hw) container_of(_hw, struct stm32_i2smclk_data, hw) 263 + 264 + static int stm32_i2s_get_parent_clk(struct stm32_i2s_data *i2s); 282 265 283 266 static int stm32_i2s_calc_clk_div(struct stm32_i2s_data *i2s, 284 267 unsigned long input_rate, ··· 333 312 cgfr_mask, cgfr); 334 313 } 335 314 315 + static bool stm32_i2s_rate_accurate(struct stm32_i2s_data *i2s, 316 + unsigned int max_rate, unsigned int rate) 317 + { 318 + struct platform_device *pdev = i2s->pdev; 319 + u64 delta, dividend; 320 + int ratio; 321 + 322 + if (!rate) { 323 + dev_err(&pdev->dev, "Unexpected null rate\n"); 324 + return false; 325 + } 326 + 327 + ratio = DIV_ROUND_CLOSEST(max_rate, rate); 328 + if (!ratio) 329 + return false; 330 + 331 + dividend = mul_u32_u32(1000000, abs(max_rate - (ratio * rate))); 332 + delta = div_u64(dividend, max_rate); 333 + 334 + if (delta <= STM32_I2S_CLK_RATE_TOLERANCE) 335 + return true; 336 + 337 + dev_dbg(&pdev->dev, "Rate [%u] not accurate\n", rate); 338 + 339 + return false; 340 + } 341 + 336 342 static int stm32_i2s_set_parent_clock(struct stm32_i2s_data *i2s, 337 343 unsigned int rate) 338 344 { ··· 378 330 "Error %d setting i2sclk parent clock\n", ret); 379 331 380 332 return ret; 333 + } 334 + 335 + static void stm32_i2s_put_parent_rate(struct stm32_i2s_data *i2s) 336 + { 337 + if (i2s->i2s_clk_flg) { 338 + i2s->i2s_clk_flg = false; 339 + clk_rate_exclusive_put(i2s->i2sclk); 340 + } 341 + } 342 + 343 + static int stm32_i2s_set_parent_rate(struct stm32_i2s_data *i2s, 344 + unsigned int rate) 345 + { 346 + struct platform_device *pdev = i2s->pdev; 347 + unsigned int i2s_clk_rate, i2s_clk_max_rate, i2s_curr_rate, i2s_new_rate; 348 + int ret, div; 349 + 350 + /* 351 + * Set maximum expected kernel clock frequency 352 + * - mclk on: 353 + * f_i2s_ck = MCKDIV * mclk-fs * fs 354 + * Here typical 256 ratio is assumed for mclk-fs 355 + * - mclk off: 356 + * f_i2s_ck = MCKDIV * FRL * fs 357 + * Where FRL=[16,32], MCKDIV=[1..256] 358 + * f_i2s_ck = i2s_clk_max_rate * 32 / 256 359 + */ 360 + if (!(rate % STM32_I2S_RATE_11K)) 361 + i2s_clk_max_rate = STM32_I2S_MAX_SAMPLE_RATE_11K * 256; 362 + else 363 + i2s_clk_max_rate = STM32_I2S_MAX_SAMPLE_RATE_8K * 256; 364 + 365 + if (!i2s->i2smclk) 366 + i2s_clk_max_rate /= 8; 367 + 368 + /* Request exclusivity, as the clock may be shared by I2S instances */ 369 + clk_rate_exclusive_get(i2s->i2sclk); 370 + i2s->i2s_clk_flg = true; 371 + 372 + /* 373 + * Check current kernel clock rate. If it gives the expected accuracy 374 + * return immediately. 375 + */ 376 + i2s_curr_rate = clk_get_rate(i2s->i2sclk); 377 + if (stm32_i2s_rate_accurate(i2s, i2s_clk_max_rate, i2s_curr_rate)) 378 + return 0; 379 + 380 + /* 381 + * Otherwise try to set the maximum rate and check the new actual rate. 382 + * If the new rate does not give the expected accuracy, try to set 383 + * lower rates for the kernel clock. 384 + */ 385 + i2s_clk_rate = i2s_clk_max_rate; 386 + div = 1; 387 + do { 388 + /* Check new rate accuracy. Return if ok */ 389 + i2s_new_rate = clk_round_rate(i2s->i2sclk, i2s_clk_rate); 390 + if (stm32_i2s_rate_accurate(i2s, i2s_clk_rate, i2s_new_rate)) { 391 + ret = clk_set_rate(i2s->i2sclk, i2s_clk_rate); 392 + if (ret) { 393 + dev_err(&pdev->dev, "Error %d setting i2s_clk_rate rate. %s", 394 + ret, ret == -EBUSY ? 395 + "Active stream rates may be in conflict\n" : "\n"); 396 + goto err; 397 + } 398 + 399 + return 0; 400 + } 401 + 402 + /* Try a lower frequency */ 403 + div++; 404 + i2s_clk_rate = i2s_clk_max_rate / div; 405 + } while (i2s_clk_rate > rate); 406 + 407 + /* no accurate rate found */ 408 + dev_err(&pdev->dev, "Failed to find an accurate rate"); 409 + 410 + err: 411 + stm32_i2s_put_parent_rate(i2s); 412 + 413 + return -EINVAL; 381 414 } 382 415 383 416 static long stm32_i2smclk_round_rate(struct clk_hw *hw, unsigned long rate, ··· 764 635 clk_rate_exclusive_put(i2s->i2smclk); 765 636 i2s->mclk_rate = 0; 766 637 } 638 + 639 + if (i2s->put_i2s_clk_rate) 640 + i2s->put_i2s_clk_rate(i2s); 641 + 767 642 return regmap_update_bits(i2s->regmap, 768 643 STM32_I2S_CGFR_REG, 769 644 I2S_CGFR_MCKOE, 0); 770 645 } 771 646 /* If master clock is used, set parent clock now */ 772 - ret = stm32_i2s_set_parent_clock(i2s, freq); 647 + ret = i2s->set_i2s_clk_rate(i2s, freq); 773 648 if (ret) 774 649 return ret; 775 650 ret = clk_set_rate_exclusive(i2s->i2smclk, freq); ··· 800 667 u32 cgfr; 801 668 int ret; 802 669 803 - if (!(rate % 11025)) 804 - clk_set_parent(i2s->i2sclk, i2s->x11kclk); 805 - else 806 - clk_set_parent(i2s->i2sclk, i2s->x8kclk); 670 + if (!i2s->mclk_rate) { 671 + ret = i2s->set_i2s_clk_rate(i2s, rate); 672 + if (ret) 673 + return ret; 674 + } 807 675 i2s_clock_rate = clk_get_rate(i2s->i2sclk); 808 676 809 677 /* ··· 1049 915 1050 916 clk_disable_unprepare(i2s->i2sclk); 1051 917 918 + /* 919 + * Release kernel clock if following conditions are fulfilled 920 + * - Master clock is not used. Kernel clock won't be released trough sysclk 921 + * - Put handler is defined. Involve that clock is managed exclusively 922 + */ 923 + if (!i2s->i2smclk && i2s->put_i2s_clk_rate) 924 + i2s->put_i2s_clk_rate(i2s); 925 + 1052 926 spin_lock_irqsave(&i2s->irq_lock, flags); 1053 927 i2s->substream = NULL; 1054 928 spin_unlock_irqrestore(&i2s->irq_lock, flags); ··· 1154 1012 return 0; 1155 1013 } 1156 1014 1015 + static const struct stm32_i2s_conf stm32_i2s_conf_h7 = { 1016 + .regmap_conf = &stm32_h7_i2s_regmap_conf, 1017 + .get_i2s_clk_parent = stm32_i2s_get_parent_clk, 1018 + }; 1019 + 1020 + static const struct stm32_i2s_conf stm32_i2s_conf_mp25 = { 1021 + .regmap_conf = &stm32_h7_i2s_regmap_conf 1022 + }; 1023 + 1157 1024 static const struct of_device_id stm32_i2s_ids[] = { 1158 - { 1159 - .compatible = "st,stm32h7-i2s", 1160 - .data = &stm32_h7_i2s_regmap_conf 1161 - }, 1025 + { .compatible = "st,stm32h7-i2s", .data = &stm32_i2s_conf_h7 }, 1026 + { .compatible = "st,stm32mp25-i2s", .data = &stm32_i2s_conf_mp25 }, 1162 1027 {}, 1163 1028 }; 1029 + 1030 + static int stm32_i2s_get_parent_clk(struct stm32_i2s_data *i2s) 1031 + { 1032 + struct device *dev = &i2s->pdev->dev; 1033 + 1034 + i2s->x8kclk = devm_clk_get(dev, "x8k"); 1035 + if (IS_ERR(i2s->x8kclk)) 1036 + return dev_err_probe(dev, PTR_ERR(i2s->x8kclk), "Cannot get x8k parent clock\n"); 1037 + 1038 + i2s->x11kclk = devm_clk_get(dev, "x11k"); 1039 + if (IS_ERR(i2s->x11kclk)) 1040 + return dev_err_probe(dev, PTR_ERR(i2s->x11kclk), "Cannot get x11k parent clock\n"); 1041 + 1042 + return 0; 1043 + } 1164 1044 1165 1045 static int stm32_i2s_parse_dt(struct platform_device *pdev, 1166 1046 struct stm32_i2s_data *i2s) ··· 1195 1031 if (!np) 1196 1032 return -ENODEV; 1197 1033 1198 - i2s->regmap_conf = device_get_match_data(&pdev->dev); 1199 - if (!i2s->regmap_conf) 1034 + i2s->conf = device_get_match_data(&pdev->dev); 1035 + if (!i2s->conf) 1200 1036 return -EINVAL; 1201 1037 1202 1038 i2s->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); ··· 1216 1052 return dev_err_probe(&pdev->dev, PTR_ERR(i2s->i2sclk), 1217 1053 "Could not get i2sclk\n"); 1218 1054 1219 - i2s->x8kclk = devm_clk_get(&pdev->dev, "x8k"); 1220 - if (IS_ERR(i2s->x8kclk)) 1221 - return dev_err_probe(&pdev->dev, PTR_ERR(i2s->x8kclk), 1222 - "Could not get x8k parent clock\n"); 1055 + if (i2s->conf->get_i2s_clk_parent) { 1056 + i2s->set_i2s_clk_rate = stm32_i2s_set_parent_clock; 1057 + } else { 1058 + i2s->set_i2s_clk_rate = stm32_i2s_set_parent_rate; 1059 + i2s->put_i2s_clk_rate = stm32_i2s_put_parent_rate; 1060 + } 1223 1061 1224 - i2s->x11kclk = devm_clk_get(&pdev->dev, "x11k"); 1225 - if (IS_ERR(i2s->x11kclk)) 1226 - return dev_err_probe(&pdev->dev, PTR_ERR(i2s->x11kclk), 1227 - "Could not get x11k parent clock\n"); 1062 + if (i2s->conf->get_i2s_clk_parent) { 1063 + ret = i2s->conf->get_i2s_clk_parent(i2s); 1064 + if (ret) 1065 + return ret; 1066 + } 1228 1067 1229 1068 /* Register mclk provider if requested */ 1230 1069 if (of_property_present(np, "#clock-cells")) { ··· 1293 1126 return ret; 1294 1127 1295 1128 i2s->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "pclk", 1296 - i2s->base, i2s->regmap_conf); 1129 + i2s->base, i2s->conf->regmap_conf); 1297 1130 if (IS_ERR(i2s->regmap)) 1298 1131 return dev_err_probe(&pdev->dev, PTR_ERR(i2s->regmap), 1299 1132 "Regmap init error\n");