@@ -200,10 +200,13 @@ enum i2s_datlen {
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
@@ -224,11 +227,14 @@ enum i2s_datlen {
224
227
* @divider: prescaler division ratio
225
228
* @div: prescaler div field
226
229
* @odd: prescaler odd field
230
+ * @i2s_clk_flg: flag set while exclusivity on I2S kernel clock is active
227
231
* @refcount: keep count of opened streams on I2S
228
232
* @ms_flg: master mode flag.
233
+ * @set_i2s_clk_rate: set I2S kernel clock rate
234
+ * @put_i2s_clk_rate: put I2S kernel clock rate
229
235
*/
230
236
struct stm32_i2s_data {
231
- const struct regmap_config * regmap_conf ;
237
+ const struct stm32_i2s_conf * conf ;
232
238
struct regmap * regmap ;
233
239
struct platform_device * pdev ;
234
240
struct snd_soc_dai_driver * dai_drv ;
@@ -249,8 +255,21 @@ struct stm32_i2s_data {
249
255
unsigned int divider ;
250
256
unsigned int div ;
251
257
bool odd ;
258
+ bool i2s_clk_flg ;
252
259
int refcount ;
253
260
int ms_flg ;
261
+ int (* set_i2s_clk_rate )(struct stm32_i2s_data * i2s , unsigned int rate );
262
+ void (* put_i2s_clk_rate )(struct stm32_i2s_data * i2s );
263
+ };
264
+
265
+ /**
266
+ * struct stm32_i2s_conf - I2S configuration
267
+ * @regmap_conf: regmap configuration pointer
268
+ * @get_i2s_clk_parent: get parent clock of I2S kernel clock
269
+ */
270
+ struct stm32_i2s_conf {
271
+ const struct regmap_config * regmap_conf ;
272
+ int (* get_i2s_clk_parent )(struct stm32_i2s_data * i2s );
254
273
};
255
274
256
275
struct stm32_i2smclk_data {
@@ -261,6 +280,8 @@ struct stm32_i2smclk_data {
261
280
262
281
#define to_mclk_data (_hw ) container_of(_hw, struct stm32_i2smclk_data, hw)
263
282
283
+ static int stm32_i2s_get_parent_clk (struct stm32_i2s_data * i2s );
284
+
264
285
static int stm32_i2s_calc_clk_div (struct stm32_i2s_data * i2s ,
265
286
unsigned long input_rate ,
266
287
unsigned long output_rate )
@@ -312,6 +333,33 @@ static int stm32_i2s_set_clk_div(struct stm32_i2s_data *i2s)
312
333
cgfr_mask , cgfr );
313
334
}
314
335
336
+ static bool stm32_i2s_rate_accurate (struct stm32_i2s_data * i2s ,
337
+ unsigned int max_rate , unsigned int rate )
338
+ {
339
+ struct platform_device * pdev = i2s -> pdev ;
340
+ u64 delta , dividend ;
341
+ int ratio ;
342
+
343
+ if (!rate ) {
344
+ dev_err (& pdev -> dev , "Unexpected null rate\n" );
345
+ return false;
346
+ }
347
+
348
+ ratio = DIV_ROUND_CLOSEST (max_rate , rate );
349
+ if (!ratio )
350
+ return false;
351
+
352
+ dividend = mul_u32_u32 (1000000 , abs (max_rate - (ratio * rate )));
353
+ delta = div_u64 (dividend , max_rate );
354
+
355
+ if (delta <= STM32_I2S_CLK_RATE_TOLERANCE )
356
+ return true;
357
+
358
+ dev_dbg (& pdev -> dev , "Rate [%u] not accurate\n" , rate );
359
+
360
+ return false;
361
+ }
362
+
315
363
static int stm32_i2s_set_parent_clock (struct stm32_i2s_data * i2s ,
316
364
unsigned int rate )
317
365
{
@@ -332,6 +380,87 @@ static int stm32_i2s_set_parent_clock(struct stm32_i2s_data *i2s,
332
380
return ret ;
333
381
}
334
382
383
+ static void stm32_i2s_put_parent_rate (struct stm32_i2s_data * i2s )
384
+ {
385
+ if (i2s -> i2s_clk_flg ) {
386
+ i2s -> i2s_clk_flg = false;
387
+ clk_rate_exclusive_put (i2s -> i2sclk );
388
+ }
389
+ }
390
+
391
+ static int stm32_i2s_set_parent_rate (struct stm32_i2s_data * i2s ,
392
+ unsigned int rate )
393
+ {
394
+ struct platform_device * pdev = i2s -> pdev ;
395
+ unsigned int i2s_clk_rate , i2s_clk_max_rate , i2s_curr_rate , i2s_new_rate ;
396
+ int ret , div ;
397
+
398
+ /*
399
+ * Set maximum expected kernel clock frequency
400
+ * - mclk on:
401
+ * f_i2s_ck = MCKDIV * mclk-fs * fs
402
+ * Here typical 256 ratio is assumed for mclk-fs
403
+ * - mclk off:
404
+ * f_i2s_ck = MCKDIV * FRL * fs
405
+ * Where FRL=[16,32], MCKDIV=[1..256]
406
+ * f_i2s_ck = i2s_clk_max_rate * 32 / 256
407
+ */
408
+ if (!(rate % STM32_I2S_RATE_11K ))
409
+ i2s_clk_max_rate = STM32_I2S_MAX_SAMPLE_RATE_11K * 256 ;
410
+ else
411
+ i2s_clk_max_rate = STM32_I2S_MAX_SAMPLE_RATE_8K * 256 ;
412
+
413
+ if (!i2s -> i2smclk )
414
+ i2s_clk_max_rate /= 8 ;
415
+
416
+ /* Request exclusivity, as the clock may be shared by I2S instances */
417
+ clk_rate_exclusive_get (i2s -> i2sclk );
418
+ i2s -> i2s_clk_flg = true;
419
+
420
+ /*
421
+ * Check current kernel clock rate. If it gives the expected accuracy
422
+ * return immediately.
423
+ */
424
+ i2s_curr_rate = clk_get_rate (i2s -> i2sclk );
425
+ if (stm32_i2s_rate_accurate (i2s , i2s_clk_max_rate , i2s_curr_rate ))
426
+ return 0 ;
427
+
428
+ /*
429
+ * Otherwise try to set the maximum rate and check the new actual rate.
430
+ * If the new rate does not give the expected accuracy, try to set
431
+ * lower rates for the kernel clock.
432
+ */
433
+ i2s_clk_rate = i2s_clk_max_rate ;
434
+ div = 1 ;
435
+ do {
436
+ /* Check new rate accuracy. Return if ok */
437
+ i2s_new_rate = clk_round_rate (i2s -> i2sclk , i2s_clk_rate );
438
+ if (stm32_i2s_rate_accurate (i2s , i2s_clk_rate , i2s_new_rate )) {
439
+ ret = clk_set_rate (i2s -> i2sclk , i2s_clk_rate );
440
+ if (ret ) {
441
+ dev_err (& pdev -> dev , "Error %d setting i2s_clk_rate rate. %s" ,
442
+ ret , ret == - EBUSY ?
443
+ "Active stream rates may be in conflict\n" : "\n" );
444
+ goto err ;
445
+ }
446
+
447
+ return 0 ;
448
+ }
449
+
450
+ /* Try a lower frequency */
451
+ div ++ ;
452
+ i2s_clk_rate = i2s_clk_max_rate / div ;
453
+ } while (i2s_clk_rate > rate );
454
+
455
+ /* no accurate rate found */
456
+ dev_err (& pdev -> dev , "Failed to find an accurate rate" );
457
+
458
+ err :
459
+ stm32_i2s_put_parent_rate (i2s );
460
+
461
+ return - EINVAL ;
462
+ }
463
+
335
464
static long stm32_i2smclk_round_rate (struct clk_hw * hw , unsigned long rate ,
336
465
unsigned long * prate )
337
466
{
@@ -635,12 +764,16 @@ static int stm32_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
635
764
clk_rate_exclusive_put (i2s -> i2smclk );
636
765
i2s -> mclk_rate = 0 ;
637
766
}
767
+
768
+ if (i2s -> put_i2s_clk_rate )
769
+ i2s -> put_i2s_clk_rate (i2s );
770
+
638
771
return regmap_update_bits (i2s -> regmap ,
639
772
STM32_I2S_CGFR_REG ,
640
773
I2S_CGFR_MCKOE , 0 );
641
774
}
642
775
/* If master clock is used, set parent clock now */
643
- ret = stm32_i2s_set_parent_clock (i2s , freq );
776
+ ret = i2s -> set_i2s_clk_rate (i2s , freq );
644
777
if (ret )
645
778
return ret ;
646
779
ret = clk_set_rate_exclusive (i2s -> i2smclk , freq );
@@ -667,10 +800,11 @@ static int stm32_i2s_configure_clock(struct snd_soc_dai *cpu_dai,
667
800
u32 cgfr ;
668
801
int ret ;
669
802
670
- if (!(rate % 11025 ))
671
- clk_set_parent (i2s -> i2sclk , i2s -> x11kclk );
672
- else
673
- clk_set_parent (i2s -> i2sclk , i2s -> x8kclk );
803
+ if (!i2s -> mclk_rate ) {
804
+ ret = i2s -> set_i2s_clk_rate (i2s , rate );
805
+ if (ret )
806
+ return ret ;
807
+ }
674
808
i2s_clock_rate = clk_get_rate (i2s -> i2sclk );
675
809
676
810
/*
@@ -915,6 +1049,14 @@ static void stm32_i2s_shutdown(struct snd_pcm_substream *substream,
915
1049
916
1050
clk_disable_unprepare (i2s -> i2sclk );
917
1051
1052
+ /*
1053
+ * Release kernel clock if following conditions are fulfilled
1054
+ * - Master clock is not used. Kernel clock won't be released trough sysclk
1055
+ * - Put handler is defined. Involve that clock is managed exclusively
1056
+ */
1057
+ if (!i2s -> i2smclk && i2s -> put_i2s_clk_rate )
1058
+ i2s -> put_i2s_clk_rate (i2s );
1059
+
918
1060
spin_lock_irqsave (& i2s -> irq_lock , flags );
919
1061
i2s -> substream = NULL ;
920
1062
spin_unlock_irqrestore (& i2s -> irq_lock , flags );
@@ -1012,14 +1154,36 @@ static int stm32_i2s_dais_init(struct platform_device *pdev,
1012
1154
return 0 ;
1013
1155
}
1014
1156
1157
+ static const struct stm32_i2s_conf stm32_i2s_conf_h7 = {
1158
+ .regmap_conf = & stm32_h7_i2s_regmap_conf ,
1159
+ .get_i2s_clk_parent = stm32_i2s_get_parent_clk ,
1160
+ };
1161
+
1162
+ static const struct stm32_i2s_conf stm32_i2s_conf_mp25 = {
1163
+ .regmap_conf = & stm32_h7_i2s_regmap_conf
1164
+ };
1165
+
1015
1166
static const struct of_device_id stm32_i2s_ids [] = {
1016
- {
1017
- .compatible = "st,stm32h7-i2s" ,
1018
- .data = & stm32_h7_i2s_regmap_conf
1019
- },
1167
+ { .compatible = "st,stm32h7-i2s" , .data = & stm32_i2s_conf_h7 },
1168
+ { .compatible = "st,stm32mp25-i2s" , .data = & stm32_i2s_conf_mp25 },
1020
1169
{},
1021
1170
};
1022
1171
1172
+ static int stm32_i2s_get_parent_clk (struct stm32_i2s_data * i2s )
1173
+ {
1174
+ struct device * dev = & i2s -> pdev -> dev ;
1175
+
1176
+ i2s -> x8kclk = devm_clk_get (dev , "x8k" );
1177
+ if (IS_ERR (i2s -> x8kclk ))
1178
+ return dev_err_probe (dev , PTR_ERR (i2s -> x8kclk ), "Cannot get x8k parent clock\n" );
1179
+
1180
+ i2s -> x11kclk = devm_clk_get (dev , "x11k" );
1181
+ if (IS_ERR (i2s -> x11kclk ))
1182
+ return dev_err_probe (dev , PTR_ERR (i2s -> x11kclk ), "Cannot get x11k parent clock\n" );
1183
+
1184
+ return 0 ;
1185
+ }
1186
+
1023
1187
static int stm32_i2s_parse_dt (struct platform_device * pdev ,
1024
1188
struct stm32_i2s_data * i2s )
1025
1189
{
@@ -1031,8 +1195,8 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev,
1031
1195
if (!np )
1032
1196
return - ENODEV ;
1033
1197
1034
- i2s -> regmap_conf = device_get_match_data (& pdev -> dev );
1035
- if (!i2s -> regmap_conf )
1198
+ i2s -> conf = device_get_match_data (& pdev -> dev );
1199
+ if (!i2s -> conf )
1036
1200
return - EINVAL ;
1037
1201
1038
1202
i2s -> base = devm_platform_get_and_ioremap_resource (pdev , 0 , & res );
@@ -1052,15 +1216,18 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev,
1052
1216
return dev_err_probe (& pdev -> dev , PTR_ERR (i2s -> i2sclk ),
1053
1217
"Could not get i2sclk\n" );
1054
1218
1055
- i2s -> x8kclk = devm_clk_get (& pdev -> dev , "x8k" );
1056
- if (IS_ERR (i2s -> x8kclk ))
1057
- return dev_err_probe (& pdev -> dev , PTR_ERR (i2s -> x8kclk ),
1058
- "Could not get x8k parent clock\n" );
1219
+ if (i2s -> conf -> get_i2s_clk_parent ) {
1220
+ i2s -> set_i2s_clk_rate = stm32_i2s_set_parent_clock ;
1221
+ } else {
1222
+ i2s -> set_i2s_clk_rate = stm32_i2s_set_parent_rate ;
1223
+ i2s -> put_i2s_clk_rate = stm32_i2s_put_parent_rate ;
1224
+ }
1059
1225
1060
- i2s -> x11kclk = devm_clk_get (& pdev -> dev , "x11k" );
1061
- if (IS_ERR (i2s -> x11kclk ))
1062
- return dev_err_probe (& pdev -> dev , PTR_ERR (i2s -> x11kclk ),
1063
- "Could not get x11k parent clock\n" );
1226
+ if (i2s -> conf -> get_i2s_clk_parent ) {
1227
+ ret = i2s -> conf -> get_i2s_clk_parent (i2s );
1228
+ if (ret )
1229
+ return ret ;
1230
+ }
1064
1231
1065
1232
/* Register mclk provider if requested */
1066
1233
if (of_property_present (np , "#clock-cells" )) {
@@ -1126,7 +1293,7 @@ static int stm32_i2s_probe(struct platform_device *pdev)
1126
1293
return ret ;
1127
1294
1128
1295
i2s -> regmap = devm_regmap_init_mmio_clk (& pdev -> dev , "pclk" ,
1129
- i2s -> base , i2s -> regmap_conf );
1296
+ i2s -> base , i2s -> conf -> regmap_conf );
1130
1297
if (IS_ERR (i2s -> regmap ))
1131
1298
return dev_err_probe (& pdev -> dev , PTR_ERR (i2s -> regmap ),
1132
1299
"Regmap init error\n" );
0 commit comments