1 // SPDX-License-Identifier: GPL-2.0-only
2 // ALSA SoC Audio Layer - Rockchip I2S/TDM Controller driver
4 // Copyright (c) 2018 Rockchip Electronics Co. Ltd.
5 // Author: Sugar Zhang <sugar.zhang@rock-chips.com>
6 // Author: Nicolas Frattaroli <frattaroli.nicolas@gmail.com>
9 #include <linux/clk-provider.h>
10 #include <linux/delay.h>
11 #include <linux/mfd/syscon.h>
12 #include <linux/module.h>
14 #include <linux/pm_runtime.h>
15 #include <linux/regmap.h>
16 #include <linux/reset.h>
17 #include <linux/spinlock.h>
18 #include <sound/dmaengine_pcm.h>
19 #include <sound/pcm_params.h>
21 #include "rockchip_i2s_tdm.h"
23 #define DRV_NAME "rockchip-i2s-tdm"
25 #define DEFAULT_MCLK_FS 256
26 #define CH_GRP_MAX 4 /* The max channel 8 / 2 */
27 #define MULTIPLEX_CH_MAX 10
40 struct rk_i2s_soc_data
{
45 const struct txrx_config
*configs
;
46 int (*init
)(struct device
*dev
, u32 addr
);
49 struct rk_i2s_tdm_dev
{
54 struct regmap
*regmap
;
56 struct snd_dmaengine_dai_dma_data capture_dma_data
;
57 struct snd_dmaengine_dai_dma_data playback_dma_data
;
58 struct reset_control
*tx_reset
;
59 struct reset_control
*rx_reset
;
60 const struct rk_i2s_soc_data
*soc_data
;
64 unsigned int frame_width
;
65 unsigned int clk_trcm
;
66 unsigned int i2s_sdis
[CH_GRP_MAX
];
67 unsigned int i2s_sdos
[CH_GRP_MAX
];
69 spinlock_t lock
; /* xfer lock */
72 struct snd_soc_dai_driver
*dai
;
75 static int to_ch_num(unsigned int val
)
89 static void i2s_tdm_disable_unprepare_mclk(struct rk_i2s_tdm_dev
*i2s_tdm
)
91 clk_disable_unprepare(i2s_tdm
->mclk_tx
);
92 clk_disable_unprepare(i2s_tdm
->mclk_rx
);
96 * i2s_tdm_prepare_enable_mclk - prepare to enable all mclks, disable them on
98 * @i2s_tdm: rk_i2s_tdm_dev struct
100 * This function attempts to enable all mclk clocks, but cleans up after
101 * itself on failure. Guarantees to balance its calls.
103 * Returns success (0) or negative errno.
105 static int i2s_tdm_prepare_enable_mclk(struct rk_i2s_tdm_dev
*i2s_tdm
)
109 ret
= clk_prepare_enable(i2s_tdm
->mclk_tx
);
112 ret
= clk_prepare_enable(i2s_tdm
->mclk_rx
);
119 clk_disable_unprepare(i2s_tdm
->mclk_tx
);
124 static int __maybe_unused
i2s_tdm_runtime_suspend(struct device
*dev
)
126 struct rk_i2s_tdm_dev
*i2s_tdm
= dev_get_drvdata(dev
);
128 regcache_cache_only(i2s_tdm
->regmap
, true);
129 i2s_tdm_disable_unprepare_mclk(i2s_tdm
);
131 clk_disable_unprepare(i2s_tdm
->hclk
);
136 static int __maybe_unused
i2s_tdm_runtime_resume(struct device
*dev
)
138 struct rk_i2s_tdm_dev
*i2s_tdm
= dev_get_drvdata(dev
);
141 ret
= clk_prepare_enable(i2s_tdm
->hclk
);
145 ret
= i2s_tdm_prepare_enable_mclk(i2s_tdm
);
149 regcache_cache_only(i2s_tdm
->regmap
, false);
150 regcache_mark_dirty(i2s_tdm
->regmap
);
152 ret
= regcache_sync(i2s_tdm
->regmap
);
159 i2s_tdm_disable_unprepare_mclk(i2s_tdm
);
161 clk_disable_unprepare(i2s_tdm
->hclk
);
166 static inline struct rk_i2s_tdm_dev
*to_info(struct snd_soc_dai
*dai
)
168 return snd_soc_dai_get_drvdata(dai
);
172 * Makes sure that both tx and rx are reset at the same time to sync lrck
175 static void rockchip_snd_xfer_sync_reset(struct rk_i2s_tdm_dev
*i2s_tdm
)
177 /* This is technically race-y.
179 * In an ideal world, we could atomically assert both resets at the
180 * same time, through an atomic bulk reset API. This API however does
181 * not exist, so what the downstream vendor code used to do was
182 * implement half a reset controller here and require the CRU to be
183 * passed to the driver as a device tree node. Violating abstractions
184 * like that is bad, especially when it influences something like the
185 * bindings which are supposed to describe the hardware, not whatever
186 * workarounds the driver needs, so it was dropped.
188 * In practice, asserting the resets one by one appears to work just
189 * fine for playback. During duplex (playback + capture) operation,
190 * this might become an issue, but that should be solved by the
191 * implementation of the aforementioned API, not by shoving a reset
192 * controller into an audio driver.
195 reset_control_assert(i2s_tdm
->tx_reset
);
196 reset_control_assert(i2s_tdm
->rx_reset
);
198 reset_control_deassert(i2s_tdm
->tx_reset
);
199 reset_control_deassert(i2s_tdm
->rx_reset
);
203 static void rockchip_snd_reset(struct reset_control
*rc
)
205 reset_control_assert(rc
);
207 reset_control_deassert(rc
);
211 static void rockchip_snd_xfer_clear(struct rk_i2s_tdm_dev
*i2s_tdm
,
214 unsigned int xfer_mask
= 0;
215 unsigned int xfer_val
= 0;
218 bool tx
= clr
& I2S_CLR_TXC
;
219 bool rx
= clr
& I2S_CLR_RXC
;
225 xfer_mask
= I2S_XFER_TXS_START
;
226 xfer_val
= I2S_XFER_TXS_STOP
;
229 xfer_mask
|= I2S_XFER_RXS_START
;
230 xfer_val
|= I2S_XFER_RXS_STOP
;
233 regmap_update_bits(i2s_tdm
->regmap
, I2S_XFER
, xfer_mask
, xfer_val
);
235 regmap_update_bits(i2s_tdm
->regmap
, I2S_CLR
, clr
, clr
);
237 regmap_read(i2s_tdm
->regmap
, I2S_CLR
, &val
);
238 /* Wait on the clear operation to finish */
241 regmap_read(i2s_tdm
->regmap
, I2S_CLR
, &val
);
244 dev_warn(i2s_tdm
->dev
, "clear failed, reset %s%s\n",
245 tx
? "tx" : "", rx
? "rx" : "");
247 rockchip_snd_xfer_sync_reset(i2s_tdm
);
249 rockchip_snd_reset(i2s_tdm
->tx_reset
);
251 rockchip_snd_reset(i2s_tdm
->rx_reset
);
257 static inline void rockchip_enable_tde(struct regmap
*regmap
)
259 regmap_update_bits(regmap
, I2S_DMACR
, I2S_DMACR_TDE_ENABLE
,
260 I2S_DMACR_TDE_ENABLE
);
263 static inline void rockchip_disable_tde(struct regmap
*regmap
)
265 regmap_update_bits(regmap
, I2S_DMACR
, I2S_DMACR_TDE_ENABLE
,
266 I2S_DMACR_TDE_DISABLE
);
269 static inline void rockchip_enable_rde(struct regmap
*regmap
)
271 regmap_update_bits(regmap
, I2S_DMACR
, I2S_DMACR_RDE_ENABLE
,
272 I2S_DMACR_RDE_ENABLE
);
275 static inline void rockchip_disable_rde(struct regmap
*regmap
)
277 regmap_update_bits(regmap
, I2S_DMACR
, I2S_DMACR_RDE_ENABLE
,
278 I2S_DMACR_RDE_DISABLE
);
281 /* only used when clk_trcm > 0 */
282 static void rockchip_snd_txrxctrl(struct snd_pcm_substream
*substream
,
283 struct snd_soc_dai
*dai
, int on
)
285 struct rk_i2s_tdm_dev
*i2s_tdm
= to_info(dai
);
288 spin_lock_irqsave(&i2s_tdm
->lock
, flags
);
290 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
291 rockchip_enable_tde(i2s_tdm
->regmap
);
293 rockchip_enable_rde(i2s_tdm
->regmap
);
295 if (++i2s_tdm
->refcount
== 1) {
296 rockchip_snd_xfer_sync_reset(i2s_tdm
);
297 regmap_update_bits(i2s_tdm
->regmap
, I2S_XFER
,
304 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
305 rockchip_disable_tde(i2s_tdm
->regmap
);
307 rockchip_disable_rde(i2s_tdm
->regmap
);
309 if (--i2s_tdm
->refcount
== 0) {
310 rockchip_snd_xfer_clear(i2s_tdm
,
311 I2S_CLR_TXC
| I2S_CLR_RXC
);
314 spin_unlock_irqrestore(&i2s_tdm
->lock
, flags
);
317 static void rockchip_snd_txctrl(struct rk_i2s_tdm_dev
*i2s_tdm
, int on
)
320 rockchip_enable_tde(i2s_tdm
->regmap
);
322 regmap_update_bits(i2s_tdm
->regmap
, I2S_XFER
,
326 rockchip_disable_tde(i2s_tdm
->regmap
);
328 rockchip_snd_xfer_clear(i2s_tdm
, I2S_CLR_TXC
);
332 static void rockchip_snd_rxctrl(struct rk_i2s_tdm_dev
*i2s_tdm
, int on
)
335 rockchip_enable_rde(i2s_tdm
->regmap
);
337 regmap_update_bits(i2s_tdm
->regmap
, I2S_XFER
,
341 rockchip_disable_rde(i2s_tdm
->regmap
);
343 rockchip_snd_xfer_clear(i2s_tdm
, I2S_CLR_RXC
);
347 static int rockchip_i2s_tdm_set_fmt(struct snd_soc_dai
*cpu_dai
,
350 struct rk_i2s_tdm_dev
*i2s_tdm
= to_info(cpu_dai
);
351 unsigned int mask
, val
, tdm_val
, txcr_val
, rxcr_val
;
353 bool is_tdm
= i2s_tdm
->tdm_mode
;
355 ret
= pm_runtime_resume_and_get(cpu_dai
->dev
);
356 if (ret
< 0 && ret
!= -EACCES
)
359 mask
= I2S_CKR_MSS_MASK
;
360 switch (fmt
& SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK
) {
361 case SND_SOC_DAIFMT_BP_FP
:
362 val
= I2S_CKR_MSS_MASTER
;
363 i2s_tdm
->is_master_mode
= true;
365 case SND_SOC_DAIFMT_BC_FC
:
366 val
= I2S_CKR_MSS_SLAVE
;
367 i2s_tdm
->is_master_mode
= false;
374 regmap_update_bits(i2s_tdm
->regmap
, I2S_CKR
, mask
, val
);
376 mask
= I2S_CKR_CKP_MASK
| I2S_CKR_TLP_MASK
| I2S_CKR_RLP_MASK
;
377 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
378 case SND_SOC_DAIFMT_NB_NF
:
379 val
= I2S_CKR_CKP_NORMAL
|
383 case SND_SOC_DAIFMT_NB_IF
:
384 val
= I2S_CKR_CKP_NORMAL
|
385 I2S_CKR_TLP_INVERTED
|
386 I2S_CKR_RLP_INVERTED
;
388 case SND_SOC_DAIFMT_IB_NF
:
389 val
= I2S_CKR_CKP_INVERTED
|
393 case SND_SOC_DAIFMT_IB_IF
:
394 val
= I2S_CKR_CKP_INVERTED
|
395 I2S_CKR_TLP_INVERTED
|
396 I2S_CKR_RLP_INVERTED
;
403 regmap_update_bits(i2s_tdm
->regmap
, I2S_CKR
, mask
, val
);
405 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
406 case SND_SOC_DAIFMT_RIGHT_J
:
407 txcr_val
= I2S_TXCR_IBM_RSJM
;
408 rxcr_val
= I2S_RXCR_IBM_RSJM
;
410 case SND_SOC_DAIFMT_LEFT_J
:
411 txcr_val
= I2S_TXCR_IBM_LSJM
;
412 rxcr_val
= I2S_RXCR_IBM_LSJM
;
414 case SND_SOC_DAIFMT_I2S
:
415 txcr_val
= I2S_TXCR_IBM_NORMAL
;
416 rxcr_val
= I2S_RXCR_IBM_NORMAL
;
418 case SND_SOC_DAIFMT_DSP_A
: /* PCM delay 1 mode */
419 txcr_val
= I2S_TXCR_TFS_PCM
| I2S_TXCR_PBM_MODE(1);
420 rxcr_val
= I2S_RXCR_TFS_PCM
| I2S_RXCR_PBM_MODE(1);
422 case SND_SOC_DAIFMT_DSP_B
: /* PCM no delay mode */
423 txcr_val
= I2S_TXCR_TFS_PCM
;
424 rxcr_val
= I2S_RXCR_TFS_PCM
;
431 mask
= I2S_TXCR_IBM_MASK
| I2S_TXCR_TFS_MASK
| I2S_TXCR_PBM_MASK
;
432 regmap_update_bits(i2s_tdm
->regmap
, I2S_TXCR
, mask
, txcr_val
);
434 mask
= I2S_RXCR_IBM_MASK
| I2S_RXCR_TFS_MASK
| I2S_RXCR_PBM_MASK
;
435 regmap_update_bits(i2s_tdm
->regmap
, I2S_RXCR
, mask
, rxcr_val
);
438 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
439 case SND_SOC_DAIFMT_RIGHT_J
:
440 val
= I2S_TXCR_TFS_TDM_I2S
;
441 tdm_val
= TDM_SHIFT_CTRL(2);
443 case SND_SOC_DAIFMT_LEFT_J
:
444 val
= I2S_TXCR_TFS_TDM_I2S
;
445 tdm_val
= TDM_SHIFT_CTRL(1);
447 case SND_SOC_DAIFMT_I2S
:
448 val
= I2S_TXCR_TFS_TDM_I2S
;
449 tdm_val
= TDM_SHIFT_CTRL(0);
451 case SND_SOC_DAIFMT_DSP_A
:
452 val
= I2S_TXCR_TFS_TDM_PCM
;
453 tdm_val
= TDM_SHIFT_CTRL(0);
455 case SND_SOC_DAIFMT_DSP_B
:
456 val
= I2S_TXCR_TFS_TDM_PCM
;
457 tdm_val
= TDM_SHIFT_CTRL(2);
464 tdm_val
|= TDM_FSYNC_WIDTH_SEL1(1);
465 tdm_val
|= TDM_FSYNC_WIDTH_HALF_FRAME
;
467 mask
= I2S_TXCR_TFS_MASK
;
468 regmap_update_bits(i2s_tdm
->regmap
, I2S_TXCR
, mask
, val
);
469 regmap_update_bits(i2s_tdm
->regmap
, I2S_RXCR
, mask
, val
);
471 mask
= TDM_FSYNC_WIDTH_SEL1_MSK
| TDM_FSYNC_WIDTH_SEL0_MSK
|
473 regmap_update_bits(i2s_tdm
->regmap
, I2S_TDM_TXCR
,
475 regmap_update_bits(i2s_tdm
->regmap
, I2S_TDM_RXCR
,
480 pm_runtime_put(cpu_dai
->dev
);
485 static void rockchip_i2s_tdm_xfer_pause(struct snd_pcm_substream
*substream
,
486 struct rk_i2s_tdm_dev
*i2s_tdm
)
490 stream
= SNDRV_PCM_STREAM_LAST
- substream
->stream
;
491 if (stream
== SNDRV_PCM_STREAM_PLAYBACK
)
492 rockchip_disable_tde(i2s_tdm
->regmap
);
494 rockchip_disable_rde(i2s_tdm
->regmap
);
496 rockchip_snd_xfer_clear(i2s_tdm
, I2S_CLR_TXC
| I2S_CLR_RXC
);
499 static void rockchip_i2s_tdm_xfer_resume(struct snd_pcm_substream
*substream
,
500 struct rk_i2s_tdm_dev
*i2s_tdm
)
504 stream
= SNDRV_PCM_STREAM_LAST
- substream
->stream
;
505 if (stream
== SNDRV_PCM_STREAM_PLAYBACK
)
506 rockchip_enable_tde(i2s_tdm
->regmap
);
508 rockchip_enable_rde(i2s_tdm
->regmap
);
510 regmap_update_bits(i2s_tdm
->regmap
, I2S_XFER
,
517 static int rockchip_i2s_ch_to_io(unsigned int ch
, bool substream_capture
)
519 if (substream_capture
) {
522 return I2S_IO_6CH_OUT_4CH_IN
;
524 return I2S_IO_4CH_OUT_6CH_IN
;
526 return I2S_IO_2CH_OUT_8CH_IN
;
528 return I2S_IO_8CH_OUT_2CH_IN
;
533 return I2S_IO_4CH_OUT_6CH_IN
;
535 return I2S_IO_6CH_OUT_4CH_IN
;
537 return I2S_IO_8CH_OUT_2CH_IN
;
539 return I2S_IO_2CH_OUT_8CH_IN
;
544 static int rockchip_i2s_io_multiplex(struct snd_pcm_substream
*substream
,
545 struct snd_soc_dai
*dai
)
547 struct rk_i2s_tdm_dev
*i2s_tdm
= to_info(dai
);
548 int usable_chs
= MULTIPLEX_CH_MAX
;
549 unsigned int val
= 0;
551 if (!i2s_tdm
->io_multiplex
)
554 if (IS_ERR_OR_NULL(i2s_tdm
->grf
)) {
555 dev_err(i2s_tdm
->dev
,
556 "io multiplex not supported for this device\n");
560 if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
) {
561 struct snd_pcm_str
*playback_str
=
562 &substream
->pcm
->streams
[SNDRV_PCM_STREAM_PLAYBACK
];
564 if (playback_str
->substream_opened
) {
565 regmap_read(i2s_tdm
->regmap
, I2S_TXCR
, &val
);
566 val
&= I2S_TXCR_CSR_MASK
;
567 usable_chs
= MULTIPLEX_CH_MAX
- to_ch_num(val
);
570 regmap_read(i2s_tdm
->regmap
, I2S_RXCR
, &val
);
571 val
&= I2S_RXCR_CSR_MASK
;
573 if (to_ch_num(val
) > usable_chs
) {
574 dev_err(i2s_tdm
->dev
,
575 "Capture channels (%d) > usable channels (%d)\n",
576 to_ch_num(val
), usable_chs
);
580 rockchip_i2s_ch_to_io(val
, true);
582 struct snd_pcm_str
*capture_str
=
583 &substream
->pcm
->streams
[SNDRV_PCM_STREAM_CAPTURE
];
585 if (capture_str
->substream_opened
) {
586 regmap_read(i2s_tdm
->regmap
, I2S_RXCR
, &val
);
587 val
&= I2S_RXCR_CSR_MASK
;
588 usable_chs
= MULTIPLEX_CH_MAX
- to_ch_num(val
);
591 regmap_read(i2s_tdm
->regmap
, I2S_TXCR
, &val
);
592 val
&= I2S_TXCR_CSR_MASK
;
594 if (to_ch_num(val
) > usable_chs
) {
595 dev_err(i2s_tdm
->dev
,
596 "Playback channels (%d) > usable channels (%d)\n",
597 to_ch_num(val
), usable_chs
);
602 val
<<= i2s_tdm
->soc_data
->grf_shift
;
603 val
|= (I2S_IO_DIRECTION_MASK
<< i2s_tdm
->soc_data
->grf_shift
) << 16;
604 regmap_write(i2s_tdm
->grf
, i2s_tdm
->soc_data
->grf_reg_offset
, val
);
609 static int rockchip_i2s_trcm_mode(struct snd_pcm_substream
*substream
,
610 struct snd_soc_dai
*dai
,
611 unsigned int div_bclk
,
612 unsigned int div_lrck
,
615 struct rk_i2s_tdm_dev
*i2s_tdm
= to_info(dai
);
618 if (!i2s_tdm
->clk_trcm
)
621 spin_lock_irqsave(&i2s_tdm
->lock
, flags
);
622 if (i2s_tdm
->refcount
)
623 rockchip_i2s_tdm_xfer_pause(substream
, i2s_tdm
);
625 regmap_update_bits(i2s_tdm
->regmap
, I2S_CLKDIV
,
626 I2S_CLKDIV_TXM_MASK
| I2S_CLKDIV_RXM_MASK
,
627 I2S_CLKDIV_TXM(div_bclk
) | I2S_CLKDIV_RXM(div_bclk
));
628 regmap_update_bits(i2s_tdm
->regmap
, I2S_CKR
,
629 I2S_CKR_TSD_MASK
| I2S_CKR_RSD_MASK
,
630 I2S_CKR_TSD(div_lrck
) | I2S_CKR_RSD(div_lrck
));
632 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
633 regmap_update_bits(i2s_tdm
->regmap
, I2S_TXCR
,
634 I2S_TXCR_VDW_MASK
| I2S_TXCR_CSR_MASK
,
637 regmap_update_bits(i2s_tdm
->regmap
, I2S_RXCR
,
638 I2S_RXCR_VDW_MASK
| I2S_RXCR_CSR_MASK
,
641 if (i2s_tdm
->refcount
)
642 rockchip_i2s_tdm_xfer_resume(substream
, i2s_tdm
);
643 spin_unlock_irqrestore(&i2s_tdm
->lock
, flags
);
648 static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream
*substream
,
649 struct snd_pcm_hw_params
*params
,
650 struct snd_soc_dai
*dai
)
652 struct rk_i2s_tdm_dev
*i2s_tdm
= to_info(dai
);
653 unsigned int val
= 0;
654 unsigned int mclk_rate
, bclk_rate
, div_bclk
= 4, div_lrck
= 64;
657 if (i2s_tdm
->is_master_mode
) {
660 if (i2s_tdm
->clk_trcm
== TRCM_TX
) {
661 mclk
= i2s_tdm
->mclk_tx
;
662 } else if (i2s_tdm
->clk_trcm
== TRCM_RX
) {
663 mclk
= i2s_tdm
->mclk_rx
;
664 } else if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
665 mclk
= i2s_tdm
->mclk_tx
;
667 mclk
= i2s_tdm
->mclk_rx
;
670 err
= clk_set_rate(mclk
, DEFAULT_MCLK_FS
* params_rate(params
));
674 mclk_rate
= clk_get_rate(mclk
);
675 bclk_rate
= i2s_tdm
->frame_width
* params_rate(params
);
679 div_bclk
= DIV_ROUND_CLOSEST(mclk_rate
, bclk_rate
);
680 div_lrck
= bclk_rate
/ params_rate(params
);
683 switch (params_format(params
)) {
684 case SNDRV_PCM_FORMAT_S8
:
685 val
|= I2S_TXCR_VDW(8);
687 case SNDRV_PCM_FORMAT_S16_LE
:
688 val
|= I2S_TXCR_VDW(16);
690 case SNDRV_PCM_FORMAT_S20_3LE
:
691 val
|= I2S_TXCR_VDW(20);
693 case SNDRV_PCM_FORMAT_S24_LE
:
694 val
|= I2S_TXCR_VDW(24);
696 case SNDRV_PCM_FORMAT_S32_LE
:
697 val
|= I2S_TXCR_VDW(32);
703 switch (params_channels(params
)) {
720 if (i2s_tdm
->clk_trcm
) {
721 rockchip_i2s_trcm_mode(substream
, dai
, div_bclk
, div_lrck
, val
);
722 } else if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
723 regmap_update_bits(i2s_tdm
->regmap
, I2S_CLKDIV
,
725 I2S_CLKDIV_TXM(div_bclk
));
726 regmap_update_bits(i2s_tdm
->regmap
, I2S_CKR
,
728 I2S_CKR_TSD(div_lrck
));
729 regmap_update_bits(i2s_tdm
->regmap
, I2S_TXCR
,
730 I2S_TXCR_VDW_MASK
| I2S_TXCR_CSR_MASK
,
733 regmap_update_bits(i2s_tdm
->regmap
, I2S_CLKDIV
,
735 I2S_CLKDIV_RXM(div_bclk
));
736 regmap_update_bits(i2s_tdm
->regmap
, I2S_CKR
,
738 I2S_CKR_RSD(div_lrck
));
739 regmap_update_bits(i2s_tdm
->regmap
, I2S_RXCR
,
740 I2S_RXCR_VDW_MASK
| I2S_RXCR_CSR_MASK
,
744 return rockchip_i2s_io_multiplex(substream
, dai
);
747 static int rockchip_i2s_tdm_trigger(struct snd_pcm_substream
*substream
,
748 int cmd
, struct snd_soc_dai
*dai
)
750 struct rk_i2s_tdm_dev
*i2s_tdm
= to_info(dai
);
753 case SNDRV_PCM_TRIGGER_START
:
754 case SNDRV_PCM_TRIGGER_RESUME
:
755 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
756 if (i2s_tdm
->clk_trcm
)
757 rockchip_snd_txrxctrl(substream
, dai
, 1);
758 else if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
759 rockchip_snd_rxctrl(i2s_tdm
, 1);
761 rockchip_snd_txctrl(i2s_tdm
, 1);
763 case SNDRV_PCM_TRIGGER_SUSPEND
:
764 case SNDRV_PCM_TRIGGER_STOP
:
765 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
766 if (i2s_tdm
->clk_trcm
)
767 rockchip_snd_txrxctrl(substream
, dai
, 0);
768 else if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
769 rockchip_snd_rxctrl(i2s_tdm
, 0);
771 rockchip_snd_txctrl(i2s_tdm
, 0);
780 static int rockchip_i2s_tdm_dai_probe(struct snd_soc_dai
*dai
)
782 struct rk_i2s_tdm_dev
*i2s_tdm
= snd_soc_dai_get_drvdata(dai
);
784 if (i2s_tdm
->has_capture
)
785 snd_soc_dai_dma_data_set_capture(dai
, &i2s_tdm
->capture_dma_data
);
786 if (i2s_tdm
->has_playback
)
787 snd_soc_dai_dma_data_set_playback(dai
, &i2s_tdm
->playback_dma_data
);
792 static int rockchip_dai_tdm_slot(struct snd_soc_dai
*dai
,
793 unsigned int tx_mask
, unsigned int rx_mask
,
794 int slots
, int slot_width
)
796 struct rk_i2s_tdm_dev
*i2s_tdm
= snd_soc_dai_get_drvdata(dai
);
797 unsigned int mask
, val
;
799 i2s_tdm
->tdm_mode
= true;
800 i2s_tdm
->frame_width
= slots
* slot_width
;
801 mask
= TDM_SLOT_BIT_WIDTH_MSK
| TDM_FRAME_WIDTH_MSK
;
802 val
= TDM_SLOT_BIT_WIDTH(slot_width
) |
803 TDM_FRAME_WIDTH(slots
* slot_width
);
804 regmap_update_bits(i2s_tdm
->regmap
, I2S_TDM_TXCR
,
806 regmap_update_bits(i2s_tdm
->regmap
, I2S_TDM_RXCR
,
812 static int rockchip_i2s_tdm_set_bclk_ratio(struct snd_soc_dai
*dai
,
815 struct rk_i2s_tdm_dev
*i2s_tdm
= snd_soc_dai_get_drvdata(dai
);
817 if (ratio
< 32 || ratio
> 512 || ratio
% 2 == 1)
820 i2s_tdm
->frame_width
= ratio
;
825 static const struct snd_soc_dai_ops rockchip_i2s_tdm_dai_ops
= {
826 .probe
= rockchip_i2s_tdm_dai_probe
,
827 .hw_params
= rockchip_i2s_tdm_hw_params
,
828 .set_bclk_ratio
= rockchip_i2s_tdm_set_bclk_ratio
,
829 .set_fmt
= rockchip_i2s_tdm_set_fmt
,
830 .set_tdm_slot
= rockchip_dai_tdm_slot
,
831 .trigger
= rockchip_i2s_tdm_trigger
,
834 static const struct snd_soc_component_driver rockchip_i2s_tdm_component
= {
836 .legacy_dai_naming
= 1,
839 static bool rockchip_i2s_tdm_wr_reg(struct device
*dev
, unsigned int reg
)
859 static bool rockchip_i2s_tdm_rd_reg(struct device
*dev
, unsigned int reg
)
883 static bool rockchip_i2s_tdm_volatile_reg(struct device
*dev
, unsigned int reg
)
898 static bool rockchip_i2s_tdm_precious_reg(struct device
*dev
, unsigned int reg
)
905 static const struct reg_default rockchip_i2s_tdm_reg_defaults
[] = {
916 static const struct regmap_config rockchip_i2s_tdm_regmap_config
= {
920 .max_register
= I2S_CLKDIV
,
921 .reg_defaults
= rockchip_i2s_tdm_reg_defaults
,
922 .num_reg_defaults
= ARRAY_SIZE(rockchip_i2s_tdm_reg_defaults
),
923 .writeable_reg
= rockchip_i2s_tdm_wr_reg
,
924 .readable_reg
= rockchip_i2s_tdm_rd_reg
,
925 .volatile_reg
= rockchip_i2s_tdm_volatile_reg
,
926 .precious_reg
= rockchip_i2s_tdm_precious_reg
,
927 .cache_type
= REGCACHE_FLAT
,
930 static int common_soc_init(struct device
*dev
, u32 addr
)
932 struct rk_i2s_tdm_dev
*i2s_tdm
= dev_get_drvdata(dev
);
933 const struct txrx_config
*configs
= i2s_tdm
->soc_data
->configs
;
934 u32 reg
= 0, val
= 0, trcm
= i2s_tdm
->clk_trcm
;
937 if (trcm
== TRCM_TXRX
)
940 if (IS_ERR_OR_NULL(i2s_tdm
->grf
)) {
941 dev_err(i2s_tdm
->dev
,
942 "no grf present but non-txrx TRCM specified\n");
946 for (i
= 0; i
< i2s_tdm
->soc_data
->config_count
; i
++) {
947 if (addr
!= configs
[i
].addr
)
949 reg
= configs
[i
].reg
;
951 val
= configs
[i
].txonly
;
953 val
= configs
[i
].rxonly
;
956 regmap_write(i2s_tdm
->grf
, reg
, val
);
962 static const struct txrx_config px30_txrx_config
[] = {
963 { 0xff060000, 0x184, PX30_I2S0_CLK_TXONLY
, PX30_I2S0_CLK_RXONLY
},
966 static const struct txrx_config rk1808_txrx_config
[] = {
967 { 0xff7e0000, 0x190, RK1808_I2S0_CLK_TXONLY
, RK1808_I2S0_CLK_RXONLY
},
970 static const struct txrx_config rk3308_txrx_config
[] = {
971 { 0xff300000, 0x308, RK3308_I2S0_CLK_TXONLY
, RK3308_I2S0_CLK_RXONLY
},
972 { 0xff310000, 0x308, RK3308_I2S1_CLK_TXONLY
, RK3308_I2S1_CLK_RXONLY
},
975 static const struct txrx_config rk3568_txrx_config
[] = {
976 { 0xfe410000, 0x504, RK3568_I2S1_CLK_TXONLY
, RK3568_I2S1_CLK_RXONLY
},
977 { 0xfe410000, 0x508, RK3568_I2S1_MCLK_TX_OE
, RK3568_I2S1_MCLK_RX_OE
},
978 { 0xfe420000, 0x508, RK3568_I2S2_MCLK_OE
, RK3568_I2S2_MCLK_OE
},
979 { 0xfe430000, 0x504, RK3568_I2S3_CLK_TXONLY
, RK3568_I2S3_CLK_RXONLY
},
980 { 0xfe430000, 0x508, RK3568_I2S3_MCLK_TXONLY
, RK3568_I2S3_MCLK_RXONLY
},
981 { 0xfe430000, 0x508, RK3568_I2S3_MCLK_OE
, RK3568_I2S3_MCLK_OE
},
984 static const struct txrx_config rv1126_txrx_config
[] = {
985 { 0xff800000, 0x10260, RV1126_I2S0_CLK_TXONLY
, RV1126_I2S0_CLK_RXONLY
},
988 static const struct rk_i2s_soc_data px30_i2s_soc_data
= {
989 .softrst_offset
= 0x0300,
990 .configs
= px30_txrx_config
,
991 .config_count
= ARRAY_SIZE(px30_txrx_config
),
992 .init
= common_soc_init
,
995 static const struct rk_i2s_soc_data rk1808_i2s_soc_data
= {
996 .softrst_offset
= 0x0300,
997 .configs
= rk1808_txrx_config
,
998 .config_count
= ARRAY_SIZE(rk1808_txrx_config
),
999 .init
= common_soc_init
,
1002 static const struct rk_i2s_soc_data rk3308_i2s_soc_data
= {
1003 .softrst_offset
= 0x0400,
1004 .grf_reg_offset
= 0x0308,
1006 .configs
= rk3308_txrx_config
,
1007 .config_count
= ARRAY_SIZE(rk3308_txrx_config
),
1008 .init
= common_soc_init
,
1011 static const struct rk_i2s_soc_data rk3568_i2s_soc_data
= {
1012 .softrst_offset
= 0x0400,
1013 .configs
= rk3568_txrx_config
,
1014 .config_count
= ARRAY_SIZE(rk3568_txrx_config
),
1015 .init
= common_soc_init
,
1018 static const struct rk_i2s_soc_data rv1126_i2s_soc_data
= {
1019 .softrst_offset
= 0x0300,
1020 .configs
= rv1126_txrx_config
,
1021 .config_count
= ARRAY_SIZE(rv1126_txrx_config
),
1022 .init
= common_soc_init
,
1025 static const struct of_device_id rockchip_i2s_tdm_match
[] = {
1026 { .compatible
= "rockchip,px30-i2s-tdm", .data
= &px30_i2s_soc_data
},
1027 { .compatible
= "rockchip,rk1808-i2s-tdm", .data
= &rk1808_i2s_soc_data
},
1028 { .compatible
= "rockchip,rk3308-i2s-tdm", .data
= &rk3308_i2s_soc_data
},
1029 { .compatible
= "rockchip,rk3568-i2s-tdm", .data
= &rk3568_i2s_soc_data
},
1030 { .compatible
= "rockchip,rk3588-i2s-tdm" },
1031 { .compatible
= "rockchip,rv1126-i2s-tdm", .data
= &rv1126_i2s_soc_data
},
1035 static const struct snd_soc_dai_driver i2s_tdm_dai
= {
1036 .ops
= &rockchip_i2s_tdm_dai_ops
,
1039 static int rockchip_i2s_tdm_init_dai(struct rk_i2s_tdm_dev
*i2s_tdm
)
1041 struct snd_soc_dai_driver
*dai
;
1042 struct property
*dma_names
;
1043 const char *dma_name
;
1044 u64 formats
= (SNDRV_PCM_FMTBIT_S8
| SNDRV_PCM_FMTBIT_S16_LE
|
1045 SNDRV_PCM_FMTBIT_S20_3LE
| SNDRV_PCM_FMTBIT_S24_LE
|
1046 SNDRV_PCM_FMTBIT_S32_LE
);
1047 struct device_node
*node
= i2s_tdm
->dev
->of_node
;
1049 of_property_for_each_string(node
, "dma-names", dma_names
, dma_name
) {
1050 if (!strcmp(dma_name
, "tx"))
1051 i2s_tdm
->has_playback
= true;
1052 if (!strcmp(dma_name
, "rx"))
1053 i2s_tdm
->has_capture
= true;
1056 dai
= devm_kmemdup(i2s_tdm
->dev
, &i2s_tdm_dai
,
1057 sizeof(*dai
), GFP_KERNEL
);
1061 if (i2s_tdm
->has_playback
) {
1062 dai
->playback
.stream_name
= "Playback";
1063 dai
->playback
.channels_min
= 2;
1064 dai
->playback
.channels_max
= 8;
1065 dai
->playback
.rates
= SNDRV_PCM_RATE_8000_192000
;
1066 dai
->playback
.formats
= formats
;
1069 if (i2s_tdm
->has_capture
) {
1070 dai
->capture
.stream_name
= "Capture";
1071 dai
->capture
.channels_min
= 2;
1072 dai
->capture
.channels_max
= 8;
1073 dai
->capture
.rates
= SNDRV_PCM_RATE_8000_192000
;
1074 dai
->capture
.formats
= formats
;
1077 if (i2s_tdm
->clk_trcm
!= TRCM_TXRX
)
1078 dai
->symmetric_rate
= 1;
1085 static int rockchip_i2s_tdm_path_check(struct rk_i2s_tdm_dev
*i2s_tdm
,
1089 unsigned int *i2s_data
;
1093 i2s_data
= i2s_tdm
->i2s_sdis
;
1095 i2s_data
= i2s_tdm
->i2s_sdos
;
1097 for (i
= 0; i
< num
; i
++) {
1098 if (i2s_data
[i
] > CH_GRP_MAX
- 1) {
1099 dev_err(i2s_tdm
->dev
,
1100 "%s path i2s_data[%d]: %d is too high, max is: %d\n",
1101 is_rx_path
? "RX" : "TX",
1102 i
, i2s_data
[i
], CH_GRP_MAX
);
1106 for (j
= 0; j
< num
; j
++) {
1110 if (i2s_data
[i
] == i2s_data
[j
]) {
1111 dev_err(i2s_tdm
->dev
,
1112 "%s path invalid routed i2s_data: [%d]%d == [%d]%d\n",
1113 is_rx_path
? "RX" : "TX",
1124 static void rockchip_i2s_tdm_tx_path_config(struct rk_i2s_tdm_dev
*i2s_tdm
,
1129 for (idx
= 0; idx
< num
; idx
++) {
1130 regmap_update_bits(i2s_tdm
->regmap
, I2S_TXCR
,
1131 I2S_TXCR_PATH_MASK(idx
),
1132 I2S_TXCR_PATH(idx
, i2s_tdm
->i2s_sdos
[idx
]));
1136 static void rockchip_i2s_tdm_rx_path_config(struct rk_i2s_tdm_dev
*i2s_tdm
,
1141 for (idx
= 0; idx
< num
; idx
++) {
1142 regmap_update_bits(i2s_tdm
->regmap
, I2S_RXCR
,
1143 I2S_RXCR_PATH_MASK(idx
),
1144 I2S_RXCR_PATH(idx
, i2s_tdm
->i2s_sdis
[idx
]));
1148 static void rockchip_i2s_tdm_path_config(struct rk_i2s_tdm_dev
*i2s_tdm
,
1149 int num
, bool is_rx_path
)
1152 rockchip_i2s_tdm_rx_path_config(i2s_tdm
, num
);
1154 rockchip_i2s_tdm_tx_path_config(i2s_tdm
, num
);
1157 static int rockchip_i2s_tdm_path_prepare(struct rk_i2s_tdm_dev
*i2s_tdm
,
1158 struct device_node
*np
,
1161 char *i2s_tx_path_prop
= "rockchip,i2s-tx-route";
1162 char *i2s_rx_path_prop
= "rockchip,i2s-rx-route";
1163 char *i2s_path_prop
;
1164 unsigned int *i2s_data
;
1168 i2s_path_prop
= i2s_rx_path_prop
;
1169 i2s_data
= i2s_tdm
->i2s_sdis
;
1171 i2s_path_prop
= i2s_tx_path_prop
;
1172 i2s_data
= i2s_tdm
->i2s_sdos
;
1175 num
= of_count_phandle_with_args(np
, i2s_path_prop
, NULL
);
1177 if (num
!= -ENOENT
) {
1178 dev_err(i2s_tdm
->dev
,
1179 "Failed to read '%s' num: %d\n",
1180 i2s_path_prop
, num
);
1184 } else if (num
!= CH_GRP_MAX
) {
1185 dev_err(i2s_tdm
->dev
,
1186 "The num: %d should be: %d\n", num
, CH_GRP_MAX
);
1190 ret
= of_property_read_u32_array(np
, i2s_path_prop
,
1193 dev_err(i2s_tdm
->dev
,
1194 "Failed to read '%s': %d\n",
1195 i2s_path_prop
, ret
);
1199 ret
= rockchip_i2s_tdm_path_check(i2s_tdm
, num
, is_rx_path
);
1201 dev_err(i2s_tdm
->dev
,
1202 "Failed to check i2s data bus: %d\n", ret
);
1206 rockchip_i2s_tdm_path_config(i2s_tdm
, num
, is_rx_path
);
1211 static int rockchip_i2s_tdm_tx_path_prepare(struct rk_i2s_tdm_dev
*i2s_tdm
,
1212 struct device_node
*np
)
1214 return rockchip_i2s_tdm_path_prepare(i2s_tdm
, np
, 0);
1217 static int rockchip_i2s_tdm_rx_path_prepare(struct rk_i2s_tdm_dev
*i2s_tdm
,
1218 struct device_node
*np
)
1220 return rockchip_i2s_tdm_path_prepare(i2s_tdm
, np
, 1);
1223 static int rockchip_i2s_tdm_probe(struct platform_device
*pdev
)
1225 struct device_node
*node
= pdev
->dev
.of_node
;
1226 struct rk_i2s_tdm_dev
*i2s_tdm
;
1227 struct resource
*res
;
1231 i2s_tdm
= devm_kzalloc(&pdev
->dev
, sizeof(*i2s_tdm
), GFP_KERNEL
);
1235 i2s_tdm
->dev
= &pdev
->dev
;
1237 spin_lock_init(&i2s_tdm
->lock
);
1238 i2s_tdm
->soc_data
= device_get_match_data(&pdev
->dev
);
1239 i2s_tdm
->frame_width
= 64;
1241 i2s_tdm
->clk_trcm
= TRCM_TXRX
;
1242 if (of_property_read_bool(node
, "rockchip,trcm-sync-tx-only"))
1243 i2s_tdm
->clk_trcm
= TRCM_TX
;
1244 if (of_property_read_bool(node
, "rockchip,trcm-sync-rx-only")) {
1245 if (i2s_tdm
->clk_trcm
) {
1246 dev_err(i2s_tdm
->dev
, "invalid trcm-sync configuration\n");
1249 i2s_tdm
->clk_trcm
= TRCM_RX
;
1252 ret
= rockchip_i2s_tdm_init_dai(i2s_tdm
);
1256 i2s_tdm
->grf
= syscon_regmap_lookup_by_phandle(node
, "rockchip,grf");
1257 i2s_tdm
->tx_reset
= devm_reset_control_get_optional_exclusive(&pdev
->dev
,
1259 if (IS_ERR(i2s_tdm
->tx_reset
)) {
1260 ret
= PTR_ERR(i2s_tdm
->tx_reset
);
1261 return dev_err_probe(i2s_tdm
->dev
, ret
,
1262 "Error in tx-m reset control\n");
1265 i2s_tdm
->rx_reset
= devm_reset_control_get_optional_exclusive(&pdev
->dev
,
1267 if (IS_ERR(i2s_tdm
->rx_reset
)) {
1268 ret
= PTR_ERR(i2s_tdm
->rx_reset
);
1269 return dev_err_probe(i2s_tdm
->dev
, ret
,
1270 "Error in rx-m reset control\n");
1273 i2s_tdm
->hclk
= devm_clk_get(&pdev
->dev
, "hclk");
1274 if (IS_ERR(i2s_tdm
->hclk
)) {
1275 return dev_err_probe(i2s_tdm
->dev
, PTR_ERR(i2s_tdm
->hclk
),
1276 "Failed to get clock hclk\n");
1279 i2s_tdm
->mclk_tx
= devm_clk_get(&pdev
->dev
, "mclk_tx");
1280 if (IS_ERR(i2s_tdm
->mclk_tx
)) {
1281 return dev_err_probe(i2s_tdm
->dev
, PTR_ERR(i2s_tdm
->mclk_tx
),
1282 "Failed to get clock mclk_tx\n");
1285 i2s_tdm
->mclk_rx
= devm_clk_get(&pdev
->dev
, "mclk_rx");
1286 if (IS_ERR(i2s_tdm
->mclk_rx
)) {
1287 return dev_err_probe(i2s_tdm
->dev
, PTR_ERR(i2s_tdm
->mclk_rx
),
1288 "Failed to get clock mclk_rx\n");
1291 i2s_tdm
->io_multiplex
=
1292 of_property_read_bool(node
, "rockchip,io-multiplex");
1294 regs
= devm_platform_get_and_ioremap_resource(pdev
, 0, &res
);
1296 return dev_err_probe(i2s_tdm
->dev
, PTR_ERR(regs
),
1297 "Failed to get resource IORESOURCE_MEM\n");
1300 i2s_tdm
->regmap
= devm_regmap_init_mmio(&pdev
->dev
, regs
,
1301 &rockchip_i2s_tdm_regmap_config
);
1302 if (IS_ERR(i2s_tdm
->regmap
)) {
1303 return dev_err_probe(i2s_tdm
->dev
, PTR_ERR(i2s_tdm
->regmap
),
1304 "Failed to initialise regmap\n");
1307 if (i2s_tdm
->has_playback
) {
1308 i2s_tdm
->playback_dma_data
.addr
= res
->start
+ I2S_TXDR
;
1309 i2s_tdm
->playback_dma_data
.addr_width
= DMA_SLAVE_BUSWIDTH_4_BYTES
;
1310 i2s_tdm
->playback_dma_data
.maxburst
= 8;
1313 if (i2s_tdm
->has_capture
) {
1314 i2s_tdm
->capture_dma_data
.addr
= res
->start
+ I2S_RXDR
;
1315 i2s_tdm
->capture_dma_data
.addr_width
= DMA_SLAVE_BUSWIDTH_4_BYTES
;
1316 i2s_tdm
->capture_dma_data
.maxburst
= 8;
1319 ret
= rockchip_i2s_tdm_tx_path_prepare(i2s_tdm
, node
);
1321 dev_err(&pdev
->dev
, "I2S TX path prepare failed: %d\n", ret
);
1325 ret
= rockchip_i2s_tdm_rx_path_prepare(i2s_tdm
, node
);
1327 dev_err(&pdev
->dev
, "I2S RX path prepare failed: %d\n", ret
);
1331 dev_set_drvdata(&pdev
->dev
, i2s_tdm
);
1333 ret
= clk_prepare_enable(i2s_tdm
->hclk
);
1335 return dev_err_probe(i2s_tdm
->dev
, ret
,
1336 "Failed to enable clock hclk\n");
1339 ret
= i2s_tdm_prepare_enable_mclk(i2s_tdm
);
1341 ret
= dev_err_probe(i2s_tdm
->dev
, ret
,
1342 "Failed to enable one or more mclks\n");
1343 goto err_disable_hclk
;
1346 pm_runtime_enable(&pdev
->dev
);
1348 regmap_update_bits(i2s_tdm
->regmap
, I2S_DMACR
, I2S_DMACR_TDL_MASK
,
1350 regmap_update_bits(i2s_tdm
->regmap
, I2S_DMACR
, I2S_DMACR_RDL_MASK
,
1352 regmap_update_bits(i2s_tdm
->regmap
, I2S_CKR
, I2S_CKR_TRCM_MASK
,
1353 i2s_tdm
->clk_trcm
<< I2S_CKR_TRCM_SHIFT
);
1355 if (i2s_tdm
->soc_data
&& i2s_tdm
->soc_data
->init
)
1356 i2s_tdm
->soc_data
->init(&pdev
->dev
, res
->start
);
1358 ret
= devm_snd_soc_register_component(&pdev
->dev
,
1359 &rockchip_i2s_tdm_component
,
1363 dev_err(&pdev
->dev
, "Could not register DAI\n");
1367 ret
= devm_snd_dmaengine_pcm_register(&pdev
->dev
, NULL
, 0);
1369 dev_err(&pdev
->dev
, "Could not register PCM\n");
1376 if (!pm_runtime_status_suspended(&pdev
->dev
))
1377 i2s_tdm_runtime_suspend(&pdev
->dev
);
1378 pm_runtime_disable(&pdev
->dev
);
1381 clk_disable_unprepare(i2s_tdm
->hclk
);
1386 static void rockchip_i2s_tdm_remove(struct platform_device
*pdev
)
1388 if (!pm_runtime_status_suspended(&pdev
->dev
))
1389 i2s_tdm_runtime_suspend(&pdev
->dev
);
1391 pm_runtime_disable(&pdev
->dev
);
1394 static int __maybe_unused
rockchip_i2s_tdm_suspend(struct device
*dev
)
1396 struct rk_i2s_tdm_dev
*i2s_tdm
= dev_get_drvdata(dev
);
1398 regcache_mark_dirty(i2s_tdm
->regmap
);
1403 static int __maybe_unused
rockchip_i2s_tdm_resume(struct device
*dev
)
1405 struct rk_i2s_tdm_dev
*i2s_tdm
= dev_get_drvdata(dev
);
1408 ret
= pm_runtime_resume_and_get(dev
);
1411 ret
= regcache_sync(i2s_tdm
->regmap
);
1412 pm_runtime_put(dev
);
1417 static const struct dev_pm_ops rockchip_i2s_tdm_pm_ops
= {
1418 SET_RUNTIME_PM_OPS(i2s_tdm_runtime_suspend
, i2s_tdm_runtime_resume
,
1420 SET_SYSTEM_SLEEP_PM_OPS(rockchip_i2s_tdm_suspend
,
1421 rockchip_i2s_tdm_resume
)
1424 static struct platform_driver rockchip_i2s_tdm_driver
= {
1425 .probe
= rockchip_i2s_tdm_probe
,
1426 .remove
= rockchip_i2s_tdm_remove
,
1429 .of_match_table
= rockchip_i2s_tdm_match
,
1430 .pm
= &rockchip_i2s_tdm_pm_ops
,
1433 module_platform_driver(rockchip_i2s_tdm_driver
);
1435 MODULE_DESCRIPTION("ROCKCHIP I2S/TDM ASoC Interface");
1436 MODULE_AUTHOR("Sugar Zhang <sugar.zhang@rock-chips.com>");
1437 MODULE_LICENSE("GPL v2");
1438 MODULE_ALIAS("platform:" DRV_NAME
);
1439 MODULE_DEVICE_TABLE(of
, rockchip_i2s_tdm_match
);