hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/sound/soc/stm/stm32_sai_sub.c
....@@ -1,26 +1,18 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * STM32 ALSA SoC Digital Audio Interface (SAI) driver.
34 *
45 * Copyright (C) 2016, STMicroelectronics - All Rights Reserved
56 * Author(s): Olivier Moysan <olivier.moysan@st.com> for STMicroelectronics.
6
- *
7
- * License terms: GPL V2.0.
8
- *
9
- * This program is free software; you can redistribute it and/or modify it
10
- * under the terms of the GNU General Public License version 2 as published by
11
- * the Free Software Foundation.
12
- *
13
- * This program is distributed in the hope that it will be useful, but
14
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16
- * details.
177 */
188
199 #include <linux/clk.h>
10
+#include <linux/clk-provider.h>
2011 #include <linux/kernel.h>
2112 #include <linux/module.h>
2213 #include <linux/of_irq.h>
2314 #include <linux/of_platform.h>
15
+#include <linux/pm_runtime.h>
2416 #include <linux/regmap.h>
2517
2618 #include <sound/asoundef.h>
....@@ -44,7 +36,6 @@
4436 #define SAI_DATASIZE_24 0x6
4537 #define SAI_DATASIZE_32 0x7
4638
47
-#define STM_SAI_FIFO_SIZE 8
4839 #define STM_SAI_DAI_NAME_SIZE 15
4940
5041 #define STM_SAI_IS_PLAYBACK(ip) ((ip)->dir == SNDRV_PCM_STREAM_PLAYBACK)
....@@ -62,11 +53,15 @@
6253 #define SAI_SYNC_EXTERNAL 0x2
6354
6455 #define STM_SAI_PROTOCOL_IS_SPDIF(ip) ((ip)->spdif)
65
-#define STM_SAI_HAS_SPDIF(x) ((x)->pdata->conf->has_spdif)
56
+#define STM_SAI_HAS_SPDIF(x) ((x)->pdata->conf.has_spdif_pdm)
57
+#define STM_SAI_HAS_PDM(x) ((x)->pdata->conf.has_spdif_pdm)
6658 #define STM_SAI_HAS_EXT_SYNC(x) (!STM_SAI_IS_F4(sai->pdata))
6759
6860 #define SAI_IEC60958_BLOCK_FRAMES 192
6961 #define SAI_IEC60958_STATUS_BYTES 24
62
+
63
+#define SAI_MCLK_NAME_LEN 32
64
+#define SAI_RATE_11K 11025
7065
7166 /**
7267 * struct stm32_sai_sub_data - private data of SAI sub block (block A or B)
....@@ -80,6 +75,7 @@
8075 * @pdata: SAI block parent data pointer
8176 * @np_sync_provider: synchronization provider node
8277 * @sai_ck: kernel clock feeding the SAI clock generator
78
+ * @sai_mclk: master clock from SAI mclk provider
8379 * @phys_addr: SAI registers physical base address
8480 * @mclk_rate: SAI block master clock frequency (Hz). set at init
8581 * @id: SAI sub block id corresponding to sub-block A or B
....@@ -98,18 +94,20 @@
9894 * @spdif_frm_cnt: S/PDIF playback frame counter
9995 * @iec958: iec958 data
10096 * @ctrl_lock: control lock
97
+ * @irq_lock: prevent race condition with IRQ
10198 */
10299 struct stm32_sai_sub_data {
103100 struct platform_device *pdev;
104101 struct regmap *regmap;
105102 const struct regmap_config *regmap_config;
106103 struct snd_dmaengine_dai_dma_data dma_params;
107
- struct snd_soc_dai_driver *cpu_dai_drv;
104
+ struct snd_soc_dai_driver cpu_dai_drv;
108105 struct snd_soc_dai *cpu_dai;
109106 struct snd_pcm_substream *substream;
110107 struct stm32_sai_data *pdata;
111108 struct device_node *np_sync_provider;
112109 struct clk *sai_ck;
110
+ struct clk *sai_mclk;
113111 dma_addr_t phys_addr;
114112 unsigned int mclk_rate;
115113 unsigned int id;
....@@ -128,6 +126,7 @@
128126 unsigned int spdif_frm_cnt;
129127 struct snd_aes_iec958 iec958;
130128 struct mutex ctrl_lock; /* protect resources accessed by controls */
129
+ spinlock_t irq_lock; /* used to prevent race condition with IRQ */
131130 };
132131
133132 enum stm32_sai_fifo_th {
....@@ -161,6 +160,7 @@
161160 {
162161 switch (reg) {
163162 case STM_SAI_DR_REGX:
163
+ case STM_SAI_SR_REGX:
164164 return true;
165165 default:
166166 return false;
....@@ -175,7 +175,6 @@
175175 case STM_SAI_FRCR_REGX:
176176 case STM_SAI_SLOTR_REGX:
177177 case STM_SAI_IMR_REGX:
178
- case STM_SAI_SR_REGX:
179178 case STM_SAI_CLRFR_REGX:
180179 case STM_SAI_DR_REGX:
181180 case STM_SAI_PDMCR_REGX:
....@@ -184,6 +183,56 @@
184183 default:
185184 return false;
186185 }
186
+}
187
+
188
+static int stm32_sai_sub_reg_up(struct stm32_sai_sub_data *sai,
189
+ unsigned int reg, unsigned int mask,
190
+ unsigned int val)
191
+{
192
+ int ret;
193
+
194
+ ret = clk_enable(sai->pdata->pclk);
195
+ if (ret < 0)
196
+ return ret;
197
+
198
+ ret = regmap_update_bits(sai->regmap, reg, mask, val);
199
+
200
+ clk_disable(sai->pdata->pclk);
201
+
202
+ return ret;
203
+}
204
+
205
+static int stm32_sai_sub_reg_wr(struct stm32_sai_sub_data *sai,
206
+ unsigned int reg, unsigned int mask,
207
+ unsigned int val)
208
+{
209
+ int ret;
210
+
211
+ ret = clk_enable(sai->pdata->pclk);
212
+ if (ret < 0)
213
+ return ret;
214
+
215
+ ret = regmap_write_bits(sai->regmap, reg, mask, val);
216
+
217
+ clk_disable(sai->pdata->pclk);
218
+
219
+ return ret;
220
+}
221
+
222
+static int stm32_sai_sub_reg_rd(struct stm32_sai_sub_data *sai,
223
+ unsigned int reg, unsigned int *val)
224
+{
225
+ int ret;
226
+
227
+ ret = clk_enable(sai->pdata->pclk);
228
+ if (ret < 0)
229
+ return ret;
230
+
231
+ ret = regmap_read(sai->regmap, reg, val);
232
+
233
+ clk_disable(sai->pdata->pclk);
234
+
235
+ return ret;
187236 }
188237
189238 static const struct regmap_config stm32_sai_sub_regmap_config_f4 = {
....@@ -195,6 +244,7 @@
195244 .volatile_reg = stm32_sai_sub_volatile_reg,
196245 .writeable_reg = stm32_sai_sub_writeable_reg,
197246 .fast_io = true,
247
+ .cache_type = REGCACHE_FLAT,
198248 };
199249
200250 static const struct regmap_config stm32_sai_sub_regmap_config_h7 = {
....@@ -206,6 +256,7 @@
206256 .volatile_reg = stm32_sai_sub_volatile_reg,
207257 .writeable_reg = stm32_sai_sub_writeable_reg,
208258 .fast_io = true,
259
+ .cache_type = REGCACHE_FLAT,
209260 };
210261
211262 static int snd_pcm_iec958_info(struct snd_kcontrol *kcontrol,
....@@ -251,6 +302,194 @@
251302 .put = snd_pcm_iec958_put,
252303 };
253304
305
+struct stm32_sai_mclk_data {
306
+ struct clk_hw hw;
307
+ unsigned long freq;
308
+ struct stm32_sai_sub_data *sai_data;
309
+};
310
+
311
+#define to_mclk_data(_hw) container_of(_hw, struct stm32_sai_mclk_data, hw)
312
+#define STM32_SAI_MAX_CLKS 1
313
+
314
+static int stm32_sai_get_clk_div(struct stm32_sai_sub_data *sai,
315
+ unsigned long input_rate,
316
+ unsigned long output_rate)
317
+{
318
+ int version = sai->pdata->conf.version;
319
+ int div;
320
+
321
+ div = DIV_ROUND_CLOSEST(input_rate, output_rate);
322
+ if (div > SAI_XCR1_MCKDIV_MAX(version)) {
323
+ dev_err(&sai->pdev->dev, "Divider %d out of range\n", div);
324
+ return -EINVAL;
325
+ }
326
+ dev_dbg(&sai->pdev->dev, "SAI divider %d\n", div);
327
+
328
+ if (input_rate % div)
329
+ dev_dbg(&sai->pdev->dev,
330
+ "Rate not accurate. requested (%ld), actual (%ld)\n",
331
+ output_rate, input_rate / div);
332
+
333
+ return div;
334
+}
335
+
336
+static int stm32_sai_set_clk_div(struct stm32_sai_sub_data *sai,
337
+ unsigned int div)
338
+{
339
+ int version = sai->pdata->conf.version;
340
+ int ret, cr1, mask;
341
+
342
+ if (div > SAI_XCR1_MCKDIV_MAX(version)) {
343
+ dev_err(&sai->pdev->dev, "Divider %d out of range\n", div);
344
+ return -EINVAL;
345
+ }
346
+
347
+ mask = SAI_XCR1_MCKDIV_MASK(SAI_XCR1_MCKDIV_WIDTH(version));
348
+ cr1 = SAI_XCR1_MCKDIV_SET(div);
349
+ ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, mask, cr1);
350
+ if (ret < 0)
351
+ dev_err(&sai->pdev->dev, "Failed to update CR1 register\n");
352
+
353
+ return ret;
354
+}
355
+
356
+static int stm32_sai_set_parent_clock(struct stm32_sai_sub_data *sai,
357
+ unsigned int rate)
358
+{
359
+ struct platform_device *pdev = sai->pdev;
360
+ struct clk *parent_clk = sai->pdata->clk_x8k;
361
+ int ret;
362
+
363
+ if (!(rate % SAI_RATE_11K))
364
+ parent_clk = sai->pdata->clk_x11k;
365
+
366
+ ret = clk_set_parent(sai->sai_ck, parent_clk);
367
+ if (ret)
368
+ dev_err(&pdev->dev, " Error %d setting sai_ck parent clock. %s",
369
+ ret, ret == -EBUSY ?
370
+ "Active stream rates conflict\n" : "\n");
371
+
372
+ return ret;
373
+}
374
+
375
+static long stm32_sai_mclk_round_rate(struct clk_hw *hw, unsigned long rate,
376
+ unsigned long *prate)
377
+{
378
+ struct stm32_sai_mclk_data *mclk = to_mclk_data(hw);
379
+ struct stm32_sai_sub_data *sai = mclk->sai_data;
380
+ int div;
381
+
382
+ div = stm32_sai_get_clk_div(sai, *prate, rate);
383
+ if (div < 0)
384
+ return div;
385
+
386
+ mclk->freq = *prate / div;
387
+
388
+ return mclk->freq;
389
+}
390
+
391
+static unsigned long stm32_sai_mclk_recalc_rate(struct clk_hw *hw,
392
+ unsigned long parent_rate)
393
+{
394
+ struct stm32_sai_mclk_data *mclk = to_mclk_data(hw);
395
+
396
+ return mclk->freq;
397
+}
398
+
399
+static int stm32_sai_mclk_set_rate(struct clk_hw *hw, unsigned long rate,
400
+ unsigned long parent_rate)
401
+{
402
+ struct stm32_sai_mclk_data *mclk = to_mclk_data(hw);
403
+ struct stm32_sai_sub_data *sai = mclk->sai_data;
404
+ int div, ret;
405
+
406
+ div = stm32_sai_get_clk_div(sai, parent_rate, rate);
407
+ if (div < 0)
408
+ return div;
409
+
410
+ ret = stm32_sai_set_clk_div(sai, div);
411
+ if (ret)
412
+ return ret;
413
+
414
+ mclk->freq = rate;
415
+
416
+ return 0;
417
+}
418
+
419
+static int stm32_sai_mclk_enable(struct clk_hw *hw)
420
+{
421
+ struct stm32_sai_mclk_data *mclk = to_mclk_data(hw);
422
+ struct stm32_sai_sub_data *sai = mclk->sai_data;
423
+
424
+ dev_dbg(&sai->pdev->dev, "Enable master clock\n");
425
+
426
+ return stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
427
+ SAI_XCR1_MCKEN, SAI_XCR1_MCKEN);
428
+}
429
+
430
+static void stm32_sai_mclk_disable(struct clk_hw *hw)
431
+{
432
+ struct stm32_sai_mclk_data *mclk = to_mclk_data(hw);
433
+ struct stm32_sai_sub_data *sai = mclk->sai_data;
434
+
435
+ dev_dbg(&sai->pdev->dev, "Disable master clock\n");
436
+
437
+ stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_MCKEN, 0);
438
+}
439
+
440
+static const struct clk_ops mclk_ops = {
441
+ .enable = stm32_sai_mclk_enable,
442
+ .disable = stm32_sai_mclk_disable,
443
+ .recalc_rate = stm32_sai_mclk_recalc_rate,
444
+ .round_rate = stm32_sai_mclk_round_rate,
445
+ .set_rate = stm32_sai_mclk_set_rate,
446
+};
447
+
448
+static int stm32_sai_add_mclk_provider(struct stm32_sai_sub_data *sai)
449
+{
450
+ struct clk_hw *hw;
451
+ struct stm32_sai_mclk_data *mclk;
452
+ struct device *dev = &sai->pdev->dev;
453
+ const char *pname = __clk_get_name(sai->sai_ck);
454
+ char *mclk_name, *p, *s = (char *)pname;
455
+ int ret, i = 0;
456
+
457
+ mclk = devm_kzalloc(dev, sizeof(*mclk), GFP_KERNEL);
458
+ if (!mclk)
459
+ return -ENOMEM;
460
+
461
+ mclk_name = devm_kcalloc(dev, sizeof(char),
462
+ SAI_MCLK_NAME_LEN, GFP_KERNEL);
463
+ if (!mclk_name)
464
+ return -ENOMEM;
465
+
466
+ /*
467
+ * Forge mclk clock name from parent clock name and suffix.
468
+ * String after "_" char is stripped in parent name.
469
+ */
470
+ p = mclk_name;
471
+ while (*s && *s != '_' && (i < (SAI_MCLK_NAME_LEN - 7))) {
472
+ *p++ = *s++;
473
+ i++;
474
+ }
475
+ STM_SAI_IS_SUB_A(sai) ? strcat(p, "a_mclk") : strcat(p, "b_mclk");
476
+
477
+ mclk->hw.init = CLK_HW_INIT(mclk_name, pname, &mclk_ops, 0);
478
+ mclk->sai_data = sai;
479
+ hw = &mclk->hw;
480
+
481
+ dev_dbg(dev, "Register master clock %s\n", mclk_name);
482
+ ret = devm_clk_hw_register(&sai->pdev->dev, hw);
483
+ if (ret) {
484
+ dev_err(dev, "mclk register returned %d\n", ret);
485
+ return ret;
486
+ }
487
+ sai->sai_mclk = hw->clk;
488
+
489
+ /* register mclk provider */
490
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
491
+}
492
+
254493 static irqreturn_t stm32_sai_isr(int irq, void *devid)
255494 {
256495 struct stm32_sai_sub_data *sai = (struct stm32_sai_sub_data *)devid;
....@@ -258,15 +497,15 @@
258497 unsigned int sr, imr, flags;
259498 snd_pcm_state_t status = SNDRV_PCM_STATE_RUNNING;
260499
261
- regmap_read(sai->regmap, STM_SAI_IMR_REGX, &imr);
262
- regmap_read(sai->regmap, STM_SAI_SR_REGX, &sr);
500
+ stm32_sai_sub_reg_rd(sai, STM_SAI_IMR_REGX, &imr);
501
+ stm32_sai_sub_reg_rd(sai, STM_SAI_SR_REGX, &sr);
263502
264503 flags = sr & imr;
265504 if (!flags)
266505 return IRQ_NONE;
267506
268
- regmap_update_bits(sai->regmap, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK,
269
- SAI_XCLRFR_MASK);
507
+ stm32_sai_sub_reg_wr(sai, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK,
508
+ SAI_XCLRFR_MASK);
270509
271510 if (!sai->substream) {
272511 dev_err(&pdev->dev, "Device stopped. Spurious IRQ 0x%x\n", sr);
....@@ -300,8 +539,10 @@
300539 status = SNDRV_PCM_STATE_XRUN;
301540 }
302541
303
- if (status != SNDRV_PCM_STATE_RUNNING)
542
+ spin_lock(&sai->irq_lock);
543
+ if (status != SNDRV_PCM_STATE_RUNNING && sai->substream)
304544 snd_pcm_stop_xrun(sai->substream);
545
+ spin_unlock(&sai->irq_lock);
305546
306547 return IRQ_HANDLED;
307548 }
....@@ -312,15 +553,39 @@
312553 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
313554 int ret;
314555
315
- if ((dir == SND_SOC_CLOCK_OUT) && sai->master) {
316
- ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
317
- SAI_XCR1_NODIV,
318
- (unsigned int)~SAI_XCR1_NODIV);
556
+ if (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk) {
557
+ ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
558
+ SAI_XCR1_NODIV,
559
+ freq ? 0 : SAI_XCR1_NODIV);
319560 if (ret < 0)
320561 return ret;
321562
322
- sai->mclk_rate = freq;
563
+ /* Assume shutdown if requested frequency is 0Hz */
564
+ if (!freq) {
565
+ /* Release mclk rate only if rate was actually set */
566
+ if (sai->mclk_rate) {
567
+ clk_rate_exclusive_put(sai->sai_mclk);
568
+ sai->mclk_rate = 0;
569
+ }
570
+ return 0;
571
+ }
572
+
573
+ /* If master clock is used, set parent clock now */
574
+ ret = stm32_sai_set_parent_clock(sai, freq);
575
+ if (ret)
576
+ return ret;
577
+
578
+ ret = clk_set_rate_exclusive(sai->sai_mclk, freq);
579
+ if (ret) {
580
+ dev_err(cpu_dai->dev,
581
+ ret == -EBUSY ?
582
+ "Active streams have incompatible rates" :
583
+ "Could not set mclk rate\n");
584
+ return ret;
585
+ }
586
+
323587 dev_dbg(cpu_dai->dev, "SAI MCLK frequency is %uHz\n", freq);
588
+ sai->mclk_rate = freq;
324589 }
325590
326591 return 0;
....@@ -369,7 +634,7 @@
369634
370635 slotr_mask |= SAI_XSLOTR_SLOTEN_MASK;
371636
372
- regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX, slotr_mask, slotr);
637
+ stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX, slotr_mask, slotr);
373638
374639 sai->slot_width = slot_width;
375640 sai->slots = slots;
....@@ -451,7 +716,7 @@
451716 cr1_mask |= SAI_XCR1_CKSTR;
452717 frcr_mask |= SAI_XFRCR_FSPOL;
453718
454
- regmap_update_bits(sai->regmap, STM_SAI_FRCR_REGX, frcr_mask, frcr);
719
+ stm32_sai_sub_reg_up(sai, STM_SAI_FRCR_REGX, frcr_mask, frcr);
455720
456721 /* DAI clock master masks */
457722 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
....@@ -479,7 +744,7 @@
479744 cr1_mask |= SAI_XCR1_SLAVE;
480745
481746 conf_update:
482
- ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1);
747
+ ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1);
483748 if (ret < 0) {
484749 dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
485750 return ret;
....@@ -495,8 +760,11 @@
495760 {
496761 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
497762 int imr, cr2, ret;
763
+ unsigned long flags;
498764
765
+ spin_lock_irqsave(&sai->irq_lock, flags);
499766 sai->substream = substream;
767
+ spin_unlock_irqrestore(&sai->irq_lock, flags);
500768
501769 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
502770 snd_pcm_hw_constraint_mask64(substream->runtime,
....@@ -513,13 +781,12 @@
513781 }
514782
515783 /* Enable ITs */
516
-
517
- regmap_update_bits(sai->regmap, STM_SAI_CLRFR_REGX,
518
- SAI_XCLRFR_MASK, SAI_XCLRFR_MASK);
784
+ stm32_sai_sub_reg_wr(sai, STM_SAI_CLRFR_REGX,
785
+ SAI_XCLRFR_MASK, SAI_XCLRFR_MASK);
519786
520787 imr = SAI_XIMR_OVRUDRIE;
521788 if (STM_SAI_IS_CAPTURE(sai)) {
522
- regmap_read(sai->regmap, STM_SAI_CR2_REGX, &cr2);
789
+ stm32_sai_sub_reg_rd(sai, STM_SAI_CR2_REGX, &cr2);
523790 if (cr2 & SAI_XCR2_MUTECNT_MASK)
524791 imr |= SAI_XIMR_MUTEDETIE;
525792 }
....@@ -529,8 +796,8 @@
529796 else
530797 imr |= SAI_XIMR_AFSDETIE | SAI_XIMR_LFSDETIE;
531798
532
- regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX,
533
- SAI_XIMR_MASK, imr);
799
+ stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX,
800
+ SAI_XIMR_MASK, imr);
534801
535802 return 0;
536803 }
....@@ -547,10 +814,10 @@
547814 * SAI fifo threshold is set to half fifo, to keep enough space
548815 * for DMA incoming bursts.
549816 */
550
- regmap_update_bits(sai->regmap, STM_SAI_CR2_REGX,
551
- SAI_XCR2_FFLUSH | SAI_XCR2_FTH_MASK,
552
- SAI_XCR2_FFLUSH |
553
- SAI_XCR2_FTH_SET(STM_SAI_FIFO_TH_HALF));
817
+ stm32_sai_sub_reg_wr(sai, STM_SAI_CR2_REGX,
818
+ SAI_XCR2_FFLUSH | SAI_XCR2_FTH_MASK,
819
+ SAI_XCR2_FFLUSH |
820
+ SAI_XCR2_FTH_SET(STM_SAI_FIFO_TH_HALF));
554821
555822 /* DS bits in CR1 not set for SPDIF (size forced to 24 bits).*/
556823 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
....@@ -571,7 +838,7 @@
571838 cr1 = SAI_XCR1_DS_SET(SAI_DATASIZE_32);
572839 break;
573840 default:
574
- dev_err(cpu_dai->dev, "Data format not supported");
841
+ dev_err(cpu_dai->dev, "Data format not supported\n");
575842 return -EINVAL;
576843 }
577844
....@@ -579,7 +846,7 @@
579846 if ((sai->slots == 2) && (params_channels(params) == 1))
580847 cr1 |= SAI_XCR1_MONO;
581848
582
- ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1);
849
+ ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1);
583850 if (ret < 0) {
584851 dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
585852 return ret;
....@@ -593,7 +860,7 @@
593860 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
594861 int slotr, slot_sz;
595862
596
- regmap_read(sai->regmap, STM_SAI_SLOTR_REGX, &slotr);
863
+ stm32_sai_sub_reg_rd(sai, STM_SAI_SLOTR_REGX, &slotr);
597864
598865 /*
599866 * If SLOTSZ is set to auto in SLOTR, align slot width on data size
....@@ -615,16 +882,16 @@
615882 sai->slots = 2;
616883
617884 /* The number of slots in the audio frame is equal to NBSLOT[3:0] + 1*/
618
- regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX,
619
- SAI_XSLOTR_NBSLOT_MASK,
620
- SAI_XSLOTR_NBSLOT_SET((sai->slots - 1)));
885
+ stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX,
886
+ SAI_XSLOTR_NBSLOT_MASK,
887
+ SAI_XSLOTR_NBSLOT_SET((sai->slots - 1)));
621888
622889 /* Set default slots mask if not already set from DT */
623890 if (!(slotr & SAI_XSLOTR_SLOTEN_MASK)) {
624891 sai->slot_mask = (1 << sai->slots) - 1;
625
- regmap_update_bits(sai->regmap,
626
- STM_SAI_SLOTR_REGX, SAI_XSLOTR_SLOTEN_MASK,
627
- SAI_XSLOTR_SLOTEN_SET(sai->slot_mask));
892
+ stm32_sai_sub_reg_up(sai,
893
+ STM_SAI_SLOTR_REGX, SAI_XSLOTR_SLOTEN_MASK,
894
+ SAI_XSLOTR_SLOTEN_SET(sai->slot_mask));
628895 }
629896
630897 dev_dbg(cpu_dai->dev, "Slots %d, slot width %d\n",
....@@ -654,14 +921,14 @@
654921 dev_dbg(cpu_dai->dev, "Frame length %d, frame active %d\n",
655922 sai->fs_length, fs_active);
656923
657
- regmap_update_bits(sai->regmap, STM_SAI_FRCR_REGX, frcr_mask, frcr);
924
+ stm32_sai_sub_reg_up(sai, STM_SAI_FRCR_REGX, frcr_mask, frcr);
658925
659926 if ((sai->fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_LSB) {
660927 offset = sai->slot_width - sai->data_size;
661928
662
- regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX,
663
- SAI_XSLOTR_FBOFF_MASK,
664
- SAI_XSLOTR_FBOFF_SET(offset));
929
+ stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX,
930
+ SAI_XSLOTR_FBOFF_MASK,
931
+ SAI_XSLOTR_FBOFF_SET(offset));
665932 }
666933 }
667934
....@@ -722,31 +989,35 @@
722989 struct snd_pcm_hw_params *params)
723990 {
724991 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
725
- int cr1, mask, div = 0;
726
- int sai_clk_rate, mclk_ratio, den, ret;
727
- int version = sai->pdata->conf->version;
992
+ int div = 0, cr1 = 0;
993
+ int sai_clk_rate, mclk_ratio, den;
728994 unsigned int rate = params_rate(params);
995
+ int ret;
729996
730
- if (!sai->mclk_rate) {
731
- dev_err(cpu_dai->dev, "Mclk rate is null\n");
732
- return -EINVAL;
997
+ if (!sai->sai_mclk) {
998
+ ret = stm32_sai_set_parent_clock(sai, rate);
999
+ if (ret)
1000
+ return ret;
7331001 }
734
-
735
- if (!(rate % 11025))
736
- clk_set_parent(sai->sai_ck, sai->pdata->clk_x11k);
737
- else
738
- clk_set_parent(sai->sai_ck, sai->pdata->clk_x8k);
7391002 sai_clk_rate = clk_get_rate(sai->sai_ck);
7401003
7411004 if (STM_SAI_IS_F4(sai->pdata)) {
742
- /*
743
- * mclk_rate = 256 * fs
744
- * MCKDIV = 0 if sai_ck < 3/2 * mclk_rate
745
- * MCKDIV = sai_ck / (2 * mclk_rate) otherwise
1005
+ /* mclk on (NODIV=0)
1006
+ * mclk_rate = 256 * fs
1007
+ * MCKDIV = 0 if sai_ck < 3/2 * mclk_rate
1008
+ * MCKDIV = sai_ck / (2 * mclk_rate) otherwise
1009
+ * mclk off (NODIV=1)
1010
+ * MCKDIV ignored. sck = sai_ck
7461011 */
747
- if (2 * sai_clk_rate >= 3 * sai->mclk_rate)
748
- div = DIV_ROUND_CLOSEST(sai_clk_rate,
749
- 2 * sai->mclk_rate);
1012
+ if (!sai->mclk_rate)
1013
+ return 0;
1014
+
1015
+ if (2 * sai_clk_rate >= 3 * sai->mclk_rate) {
1016
+ div = stm32_sai_get_clk_div(sai, sai_clk_rate,
1017
+ 2 * sai->mclk_rate);
1018
+ if (div < 0)
1019
+ return div;
1020
+ }
7501021 } else {
7511022 /*
7521023 * TDM mode :
....@@ -758,13 +1029,14 @@
7581029 * Note: NOMCK/NODIV correspond to same bit.
7591030 */
7601031 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
761
- div = DIV_ROUND_CLOSEST(sai_clk_rate,
762
- (params_rate(params) * 128));
1032
+ div = stm32_sai_get_clk_div(sai, sai_clk_rate,
1033
+ rate * 128);
1034
+ if (div < 0)
1035
+ return div;
7631036 } else {
7641037 if (sai->mclk_rate) {
7651038 mclk_ratio = sai->mclk_rate / rate;
7661039 if (mclk_ratio == 512) {
767
- mask = SAI_XCR1_OSR;
7681040 cr1 = SAI_XCR1_OSR;
7691041 } else if (mclk_ratio != 256) {
7701042 dev_err(cpu_dai->dev,
....@@ -772,31 +1044,27 @@
7721044 mclk_ratio);
7731045 return -EINVAL;
7741046 }
775
- div = DIV_ROUND_CLOSEST(sai_clk_rate,
776
- sai->mclk_rate);
1047
+
1048
+ stm32_sai_sub_reg_up(sai,
1049
+ STM_SAI_CR1_REGX,
1050
+ SAI_XCR1_OSR, cr1);
1051
+
1052
+ div = stm32_sai_get_clk_div(sai, sai_clk_rate,
1053
+ sai->mclk_rate);
1054
+ if (div < 0)
1055
+ return div;
7771056 } else {
7781057 /* mclk-fs not set, master clock not active */
7791058 den = sai->fs_length * params_rate(params);
780
- div = DIV_ROUND_CLOSEST(sai_clk_rate, den);
1059
+ div = stm32_sai_get_clk_div(sai, sai_clk_rate,
1060
+ den);
1061
+ if (div < 0)
1062
+ return div;
7811063 }
7821064 }
7831065 }
7841066
785
- if (div > SAI_XCR1_MCKDIV_MAX(version)) {
786
- dev_err(cpu_dai->dev, "Divider %d out of range\n", div);
787
- return -EINVAL;
788
- }
789
- dev_dbg(cpu_dai->dev, "SAI clock %d, divider %d\n", sai_clk_rate, div);
790
-
791
- mask = SAI_XCR1_MCKDIV_MASK(SAI_XCR1_MCKDIV_WIDTH(version));
792
- cr1 = SAI_XCR1_MCKDIV_SET(div);
793
- ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, mask, cr1);
794
- if (ret < 0) {
795
- dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
796
- return ret;
797
- }
798
-
799
- return 0;
1067
+ return stm32_sai_set_clk_div(sai, div);
8001068 }
8011069
8021070 static int stm32_sai_hw_params(struct snd_pcm_substream *substream,
....@@ -841,12 +1109,12 @@
8411109 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
8421110 dev_dbg(cpu_dai->dev, "Enable DMA and SAI\n");
8431111
844
- regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
845
- SAI_XCR1_DMAEN, SAI_XCR1_DMAEN);
1112
+ stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
1113
+ SAI_XCR1_DMAEN, SAI_XCR1_DMAEN);
8461114
8471115 /* Enable SAI */
848
- ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
849
- SAI_XCR1_SAIEN, SAI_XCR1_SAIEN);
1116
+ ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
1117
+ SAI_XCR1_SAIEN, SAI_XCR1_SAIEN);
8501118 if (ret < 0)
8511119 dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
8521120 break;
....@@ -855,16 +1123,16 @@
8551123 case SNDRV_PCM_TRIGGER_STOP:
8561124 dev_dbg(cpu_dai->dev, "Disable DMA and SAI\n");
8571125
858
- regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX,
859
- SAI_XIMR_MASK, 0);
1126
+ stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX,
1127
+ SAI_XIMR_MASK, 0);
8601128
861
- regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
862
- SAI_XCR1_SAIEN,
863
- (unsigned int)~SAI_XCR1_SAIEN);
1129
+ stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
1130
+ SAI_XCR1_SAIEN,
1131
+ (unsigned int)~SAI_XCR1_SAIEN);
8641132
865
- ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
866
- SAI_XCR1_DMAEN,
867
- (unsigned int)~SAI_XCR1_DMAEN);
1133
+ ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
1134
+ SAI_XCR1_DMAEN,
1135
+ (unsigned int)~SAI_XCR1_DMAEN);
8681136 if (ret < 0)
8691137 dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
8701138
....@@ -882,14 +1150,15 @@
8821150 struct snd_soc_dai *cpu_dai)
8831151 {
8841152 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
1153
+ unsigned long flags;
8851154
886
- regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0);
887
-
888
- regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, SAI_XCR1_NODIV,
889
- SAI_XCR1_NODIV);
1155
+ stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0);
8901156
8911157 clk_disable_unprepare(sai->sai_ck);
1158
+
1159
+ spin_lock_irqsave(&sai->irq_lock, flags);
8921160 sai->substream = NULL;
1161
+ spin_unlock_irqrestore(&sai->irq_lock, flags);
8931162 }
8941163
8951164 static int stm32_sai_pcm_new(struct snd_soc_pcm_runtime *rtd,
....@@ -910,7 +1179,9 @@
9101179 static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai)
9111180 {
9121181 struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
913
- int cr1 = 0, cr1_mask;
1182
+ int cr1 = 0, cr1_mask, ret;
1183
+
1184
+ sai->cpu_dai = cpu_dai;
9141185
9151186 sai->dma_params.addr = (dma_addr_t)(sai->phys_addr + STM_SAI_DR_REGX);
9161187 /*
....@@ -919,6 +1190,8 @@
9191190 * constraints).
9201191 */
9211192 sai->dma_params.maxburst = 4;
1193
+ if (sai->pdata->conf.fifo_size < 8)
1194
+ sai->dma_params.maxburst = 1;
9221195 /* Buswidth will be set by framework at runtime */
9231196 sai->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
9241197
....@@ -938,14 +1211,16 @@
9381211 /* Configure synchronization */
9391212 if (sai->sync == SAI_SYNC_EXTERNAL) {
9401213 /* Configure synchro client and provider */
941
- sai->pdata->set_sync(sai->pdata, sai->np_sync_provider,
942
- sai->synco, sai->synci);
1214
+ ret = sai->pdata->set_sync(sai->pdata, sai->np_sync_provider,
1215
+ sai->synco, sai->synci);
1216
+ if (ret)
1217
+ return ret;
9431218 }
9441219
9451220 cr1_mask |= SAI_XCR1_SYNCEN_MASK;
9461221 cr1 |= SAI_XCR1_SYNCEN_SET(sai->sync);
9471222
948
- return regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1);
1223
+ return stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1);
9491224 }
9501225
9511226 static const struct snd_soc_dai_ops stm32_sai_pcm_dai_ops = {
....@@ -963,8 +1238,8 @@
9631238 void *buf, unsigned long bytes)
9641239 {
9651240 struct snd_pcm_runtime *runtime = substream->runtime;
966
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
967
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1241
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
1242
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
9681243 struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
9691244 int *ptr = (int *)(runtime->dma_area + hwoff +
9701245 channel * (runtime->dma_bytes / runtime->channels));
....@@ -1013,8 +1288,7 @@
10131288 .periods_max = 8,
10141289 };
10151290
1016
-static struct snd_soc_dai_driver stm32_sai_playback_dai[] = {
1017
-{
1291
+static struct snd_soc_dai_driver stm32_sai_playback_dai = {
10181292 .probe = stm32_sai_dai_probe,
10191293 .pcm_new = stm32_sai_pcm_new,
10201294 .id = 1, /* avoid call to fmt_single_name() */
....@@ -1031,11 +1305,9 @@
10311305 SNDRV_PCM_FMTBIT_S32_LE,
10321306 },
10331307 .ops = &stm32_sai_pcm_dai_ops,
1034
- }
10351308 };
10361309
1037
-static struct snd_soc_dai_driver stm32_sai_capture_dai[] = {
1038
-{
1310
+static struct snd_soc_dai_driver stm32_sai_capture_dai = {
10391311 .probe = stm32_sai_dai_probe,
10401312 .id = 1, /* avoid call to fmt_single_name() */
10411313 .capture = {
....@@ -1051,7 +1323,6 @@
10511323 SNDRV_PCM_FMTBIT_S32_LE,
10521324 },
10531325 .ops = &stm32_sai_pcm_dai_ops,
1054
- }
10551326 };
10561327
10571328 static const struct snd_dmaengine_pcm_config stm32_sai_pcm_config = {
....@@ -1098,14 +1369,21 @@
10981369 sai->phys_addr = res->start;
10991370
11001371 sai->regmap_config = &stm32_sai_sub_regmap_config_f4;
1101
- /* Note: PDM registers not available for H7 sub-block B */
1102
- if (STM_SAI_IS_H7(sai->pdata) && STM_SAI_IS_SUB_A(sai))
1372
+ /* Note: PDM registers not available for sub-block B */
1373
+ if (STM_SAI_HAS_PDM(sai) && STM_SAI_IS_SUB_A(sai))
11031374 sai->regmap_config = &stm32_sai_sub_regmap_config_h7;
11041375
1105
- sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "sai_ck",
1106
- base, sai->regmap_config);
1376
+ /*
1377
+ * Do not manage peripheral clock through regmap framework as this
1378
+ * can lead to circular locking issue with sai master clock provider.
1379
+ * Manage peripheral clock directly in driver instead.
1380
+ */
1381
+ sai->regmap = devm_regmap_init_mmio(&pdev->dev, base,
1382
+ sai->regmap_config);
11071383 if (IS_ERR(sai->regmap)) {
1108
- dev_err(&pdev->dev, "Failed to initialize MMIO\n");
1384
+ if (PTR_ERR(sai->regmap) != -EPROBE_DEFER)
1385
+ dev_err(&pdev->dev, "Regmap init error %ld\n",
1386
+ PTR_ERR(sai->regmap));
11091387 return PTR_ERR(sai->regmap);
11101388 }
11111389
....@@ -1143,16 +1421,15 @@
11431421 sai->sync = SAI_SYNC_NONE;
11441422 if (args.np) {
11451423 if (args.np == np) {
1146
- dev_err(&pdev->dev, "%s sync own reference\n",
1147
- np->name);
1424
+ dev_err(&pdev->dev, "%pOFn sync own reference\n", np);
11481425 of_node_put(args.np);
11491426 return -EINVAL;
11501427 }
11511428
11521429 sai->np_sync_provider = of_get_parent(args.np);
11531430 if (!sai->np_sync_provider) {
1154
- dev_err(&pdev->dev, "%s parent node not found\n",
1155
- np->name);
1431
+ dev_err(&pdev->dev, "%pOFn parent node not found\n",
1432
+ np);
11561433 of_node_put(args.np);
11571434 return -ENODEV;
11581435 }
....@@ -1197,32 +1474,32 @@
11971474 of_node_put(args.np);
11981475 sai->sai_ck = devm_clk_get(&pdev->dev, "sai_ck");
11991476 if (IS_ERR(sai->sai_ck)) {
1200
- dev_err(&pdev->dev, "Missing kernel clock sai_ck\n");
1477
+ if (PTR_ERR(sai->sai_ck) != -EPROBE_DEFER)
1478
+ dev_err(&pdev->dev, "Missing kernel clock sai_ck: %ld\n",
1479
+ PTR_ERR(sai->sai_ck));
12011480 return PTR_ERR(sai->sai_ck);
12021481 }
12031482
1204
- return 0;
1205
-}
1483
+ ret = clk_prepare(sai->pdata->pclk);
1484
+ if (ret < 0)
1485
+ return ret;
12061486
1207
-static int stm32_sai_sub_dais_init(struct platform_device *pdev,
1208
- struct stm32_sai_sub_data *sai)
1209
-{
1210
- sai->cpu_dai_drv = devm_kzalloc(&pdev->dev,
1211
- sizeof(struct snd_soc_dai_driver),
1212
- GFP_KERNEL);
1213
- if (!sai->cpu_dai_drv)
1214
- return -ENOMEM;
1487
+ if (STM_SAI_IS_F4(sai->pdata))
1488
+ return 0;
12151489
1216
- if (STM_SAI_IS_PLAYBACK(sai)) {
1217
- memcpy(sai->cpu_dai_drv, &stm32_sai_playback_dai,
1218
- sizeof(stm32_sai_playback_dai));
1219
- sai->cpu_dai_drv->playback.stream_name = sai->cpu_dai_drv->name;
1490
+ /* Register mclk provider if requested */
1491
+ if (of_find_property(np, "#clock-cells", NULL)) {
1492
+ ret = stm32_sai_add_mclk_provider(sai);
1493
+ if (ret < 0)
1494
+ return ret;
12201495 } else {
1221
- memcpy(sai->cpu_dai_drv, &stm32_sai_capture_dai,
1222
- sizeof(stm32_sai_capture_dai));
1223
- sai->cpu_dai_drv->capture.stream_name = sai->cpu_dai_drv->name;
1496
+ sai->sai_mclk = devm_clk_get(&pdev->dev, "MCLK");
1497
+ if (IS_ERR(sai->sai_mclk)) {
1498
+ if (PTR_ERR(sai->sai_mclk) != -ENOENT)
1499
+ return PTR_ERR(sai->sai_mclk);
1500
+ sai->sai_mclk = NULL;
1501
+ }
12241502 }
1225
- sai->cpu_dai_drv->name = dev_name(&pdev->dev);
12261503
12271504 return 0;
12281505 }
....@@ -1245,6 +1522,7 @@
12451522
12461523 sai->pdev = pdev;
12471524 mutex_init(&sai->ctrl_lock);
1525
+ spin_lock_init(&sai->irq_lock);
12481526 platform_set_drvdata(pdev, sai);
12491527
12501528 sai->pdata = dev_get_drvdata(pdev->dev.parent);
....@@ -1257,9 +1535,11 @@
12571535 if (ret)
12581536 return ret;
12591537
1260
- ret = stm32_sai_sub_dais_init(pdev, sai);
1261
- if (ret)
1262
- return ret;
1538
+ if (STM_SAI_IS_PLAYBACK(sai))
1539
+ sai->cpu_dai_drv = stm32_sai_playback_dai;
1540
+ else
1541
+ sai->cpu_dai_drv = stm32_sai_capture_dai;
1542
+ sai->cpu_dai_drv.name = dev_name(&pdev->dev);
12631543
12641544 ret = devm_request_irq(&pdev->dev, sai->pdata->irq, stm32_sai_isr,
12651545 IRQF_SHARED, dev_name(&pdev->dev), sai);
....@@ -1268,29 +1548,88 @@
12681548 return ret;
12691549 }
12701550
1271
- ret = devm_snd_soc_register_component(&pdev->dev, &stm32_component,
1272
- sai->cpu_dai_drv, 1);
1273
- if (ret)
1274
- return ret;
1275
-
12761551 if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
12771552 conf = &stm32_sai_pcm_config_spdif;
12781553
1279
- ret = devm_snd_dmaengine_pcm_register(&pdev->dev, conf, 0);
1554
+ ret = snd_dmaengine_pcm_register(&pdev->dev, conf, 0);
12801555 if (ret) {
1281
- dev_err(&pdev->dev, "Could not register pcm dma\n");
1556
+ if (ret != -EPROBE_DEFER)
1557
+ dev_err(&pdev->dev, "Could not register pcm dma\n");
12821558 return ret;
12831559 }
12841560
1561
+ ret = snd_soc_register_component(&pdev->dev, &stm32_component,
1562
+ &sai->cpu_dai_drv, 1);
1563
+ if (ret) {
1564
+ snd_dmaengine_pcm_unregister(&pdev->dev);
1565
+ return ret;
1566
+ }
1567
+
1568
+ pm_runtime_enable(&pdev->dev);
1569
+
12851570 return 0;
12861571 }
1572
+
1573
+static int stm32_sai_sub_remove(struct platform_device *pdev)
1574
+{
1575
+ struct stm32_sai_sub_data *sai = dev_get_drvdata(&pdev->dev);
1576
+
1577
+ clk_unprepare(sai->pdata->pclk);
1578
+ snd_dmaengine_pcm_unregister(&pdev->dev);
1579
+ snd_soc_unregister_component(&pdev->dev);
1580
+ pm_runtime_disable(&pdev->dev);
1581
+
1582
+ return 0;
1583
+}
1584
+
1585
+#ifdef CONFIG_PM_SLEEP
1586
+static int stm32_sai_sub_suspend(struct device *dev)
1587
+{
1588
+ struct stm32_sai_sub_data *sai = dev_get_drvdata(dev);
1589
+ int ret;
1590
+
1591
+ ret = clk_enable(sai->pdata->pclk);
1592
+ if (ret < 0)
1593
+ return ret;
1594
+
1595
+ regcache_cache_only(sai->regmap, true);
1596
+ regcache_mark_dirty(sai->regmap);
1597
+
1598
+ clk_disable(sai->pdata->pclk);
1599
+
1600
+ return 0;
1601
+}
1602
+
1603
+static int stm32_sai_sub_resume(struct device *dev)
1604
+{
1605
+ struct stm32_sai_sub_data *sai = dev_get_drvdata(dev);
1606
+ int ret;
1607
+
1608
+ ret = clk_enable(sai->pdata->pclk);
1609
+ if (ret < 0)
1610
+ return ret;
1611
+
1612
+ regcache_cache_only(sai->regmap, false);
1613
+ ret = regcache_sync(sai->regmap);
1614
+
1615
+ clk_disable(sai->pdata->pclk);
1616
+
1617
+ return ret;
1618
+}
1619
+#endif /* CONFIG_PM_SLEEP */
1620
+
1621
+static const struct dev_pm_ops stm32_sai_sub_pm_ops = {
1622
+ SET_SYSTEM_SLEEP_PM_OPS(stm32_sai_sub_suspend, stm32_sai_sub_resume)
1623
+};
12871624
12881625 static struct platform_driver stm32_sai_sub_driver = {
12891626 .driver = {
12901627 .name = "st,stm32-sai-sub",
12911628 .of_match_table = stm32_sai_sub_ids,
1629
+ .pm = &stm32_sai_sub_pm_ops,
12921630 },
12931631 .probe = stm32_sai_sub_probe,
1632
+ .remove = stm32_sai_sub_remove,
12941633 };
12951634
12961635 module_platform_driver(stm32_sai_sub_driver);