mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
Merge commit 'd5fc25e5c360c02b66fe44a372518e89eb6dd34f'
* commit 'd5fc25e5c360c02b66fe44a372518e89eb6dd34f': ASoC: rockchip: asrc: support rockchip asrc arm64: configs: rockchip_linux_defconfig: enable CONFIG_SND_SOC_ROCKCHIP_ASRC arm64: dts: rockchip: rk3576: add asrc node ASoC: rockchip: multicodecs: support DPCM arm64: dts: rockchip: add kernel logo for rk3576-rk628 hdmi2gvi ASoC: rockchip: i2s-tdm: Check stream is valid ASoC: rockchip: sai: Check stream is valid ASoC: hdmi-codec: Add support for HDMI-TX DLP ASoC: rockchip: Add debug for TRCM ASoC: rockchip: i2s-tdm: Optimize WL for TDM mode ASoC: rockchip: i2s_tdm: Fix params check for TDM mode Change-Id: I627e74d9ccda4677646fd57e6587f6139e0c7f8c
This commit is contained in:
@@ -126,11 +126,25 @@
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* uboot does not support 4k resolution
|
||||
*/
|
||||
&route_hdmi {
|
||||
status = "disabled";
|
||||
status = "okay";
|
||||
force-bus-format = <MEDIA_BUS_FMT_RGB888_1X24>;
|
||||
force-output;
|
||||
force_timing {
|
||||
clock-frequency = <594000000>;
|
||||
hactive = <3840>;
|
||||
vactive = <2160>;
|
||||
hback-porch = <296>;
|
||||
hfront-porch = <176>;
|
||||
vback-porch = <72>;
|
||||
vfront-porch = <8>;
|
||||
hsync-len = <88>;
|
||||
vsync-len = <10>;
|
||||
hsync-active = <1>;
|
||||
vsync-active = <1>;
|
||||
de-active = <0>;
|
||||
pixelclk-active = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
&hdmi_sound {
|
||||
|
||||
@@ -4602,6 +4602,78 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
asrc0: asrc@2a690000 {
|
||||
compatible = "rockchip,rk3576-asrc";
|
||||
reg = <0x0 0x2a690000 0x0 0x1000>;
|
||||
interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cru CLK_ASRC_4CH_0>, <&cru HCLK_ASRC_4CH_0>,
|
||||
<&cru LCLK_ASRC_SRC_0>, <&cru LCLK_ASRC_SRC_1>;
|
||||
clock-names = "mclk", "hclk", "cru_src0", "cru_src1";
|
||||
dmas = <&dmac2 17>, <&dmac2 18>;
|
||||
dma-names = "rx", "tx";
|
||||
power-domains = <&power RK3576_PD_AUDIO>;
|
||||
rockchip,grf = <&sys_grf>;
|
||||
resets = <&cru SRST_ASRC_4CH_0>, <&cru SRST_H_ASRC_4CH_0>;
|
||||
reset-names = "m", "h";
|
||||
#sound-dai-cells = <0>;
|
||||
sound-name-prefix = "ASRC0";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
asrc1: asrc@2a6a0000 {
|
||||
compatible = "rockchip,rk3576-asrc";
|
||||
reg = <0x0 0x2a6a0000 0x0 0x1000>;
|
||||
interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cru CLK_ASRC_4CH_1>, <&cru HCLK_ASRC_4CH_1>,
|
||||
<&cru LCLK_ASRC_SRC_0>, <&cru LCLK_ASRC_SRC_1>;
|
||||
clock-names = "mclk", "hclk", "cru_src0", "cru_src1";
|
||||
dmas = <&dmac2 25>, <&dmac2 26>;
|
||||
dma-names = "rx", "tx";
|
||||
power-domains = <&power RK3576_PD_AUDIO>;
|
||||
rockchip,grf = <&sys_grf>;
|
||||
resets = <&cru SRST_ASRC_4CH_1>, <&cru SRST_H_ASRC_4CH_1>;
|
||||
reset-names = "m", "h";
|
||||
#sound-dai-cells = <0>;
|
||||
sound-name-prefix = "ASRC1";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
asrc2: asrc@2a6b0000 {
|
||||
compatible = "rockchip,rk3576-asrc";
|
||||
reg = <0x0 0x2a6b0000 0x0 0x1000>;
|
||||
interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cru CLK_ASRC_2CH_0>, <&cru HCLK_ASRC_2CH_0>,
|
||||
<&cru LCLK_ASRC_SRC_0>, <&cru LCLK_ASRC_SRC_1>;
|
||||
clock-names = "mclk", "hclk", "cru_src0", "cru_src1";
|
||||
dmas = <&dmac0 27>, <&dmac0 28>;
|
||||
dma-names = "rx", "tx";
|
||||
power-domains = <&power RK3576_PD_AUDIO>;
|
||||
rockchip,grf = <&sys_grf>;
|
||||
resets = <&cru SRST_ASRC_2CH_0>, <&cru SRST_H_ASRC_2CH_0>;
|
||||
reset-names = "m", "h";
|
||||
#sound-dai-cells = <0>;
|
||||
sound-name-prefix = "ASRC2";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
asrc3: asrc@2a6c0000 {
|
||||
compatible = "rockchip,rk3576-asrc";
|
||||
reg = <0x0 0x2a6c0000 0x0 0x1000>;
|
||||
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cru CLK_ASRC_2CH_1>, <&cru HCLK_ASRC_2CH_1>,
|
||||
<&cru LCLK_ASRC_SRC_0>, <&cru LCLK_ASRC_SRC_1>;
|
||||
clock-names = "mclk", "hclk", "cru_src0", "cru_src1";
|
||||
dmas = <&dmac1 27>, <&dmac1 28>;
|
||||
dma-names = "rx", "tx";
|
||||
power-domains = <&power RK3576_PD_AUDIO>;
|
||||
rockchip,grf = <&sys_grf>;
|
||||
resets = <&cru SRST_ASRC_2CH_1>, <&cru SRST_H_ASRC_2CH_1>;
|
||||
reset-names = "m", "h";
|
||||
#sound-dai-cells = <0>;
|
||||
sound-name-prefix = "ASRC3";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
acdcdig_dsm: acdcdig-dsm@2a6d0000 {
|
||||
compatible = "rockchip,rk3576-dsm";
|
||||
reg = <0x0 0x2a6d0000 0x0 0x1000>;
|
||||
|
||||
@@ -406,6 +406,7 @@ CONFIG_SND_SEQ_DUMMY=y
|
||||
CONFIG_SND_USB_AUDIO=y
|
||||
CONFIG_SND_SOC=y
|
||||
CONFIG_SND_SOC_ROCKCHIP=y
|
||||
CONFIG_SND_SOC_ROCKCHIP_ASRC=y
|
||||
CONFIG_SND_SOC_ROCKCHIP_DLP_PCM=y
|
||||
CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=y
|
||||
CONFIG_SND_SOC_ROCKCHIP_MULTI_DAIS=y
|
||||
|
||||
@@ -272,6 +272,7 @@ struct hdmi_codec_priv {
|
||||
struct mutex lock;
|
||||
bool busy;
|
||||
bool eld_bypass;
|
||||
bool tx_dlp;
|
||||
struct snd_soc_jack *jack;
|
||||
unsigned int jack_status;
|
||||
u8 iec_status[AES_IEC958_STATUS_SIZE];
|
||||
@@ -460,6 +461,9 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream,
|
||||
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
|
||||
int ret = 0;
|
||||
|
||||
if (hcp->tx_dlp && substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&hcp->lock);
|
||||
if (hcp->busy) {
|
||||
dev_err(dai->dev, "Only one simultaneous stream supported!\n");
|
||||
@@ -500,6 +504,9 @@ static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
|
||||
{
|
||||
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (hcp->tx_dlp && substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
|
||||
return;
|
||||
|
||||
hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
|
||||
hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);
|
||||
|
||||
@@ -561,6 +568,9 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (hcp->tx_dlp && substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
|
||||
return 0;
|
||||
|
||||
if (!hcp->hcd.ops->hw_params)
|
||||
return 0;
|
||||
|
||||
@@ -602,6 +612,9 @@ static int hdmi_codec_prepare(struct snd_pcm_substream *substream,
|
||||
struct hdmi_codec_params hp;
|
||||
int ret;
|
||||
|
||||
if (hcp->tx_dlp && substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
|
||||
return 0;
|
||||
|
||||
if (!hcp->hcd.ops->prepare)
|
||||
return 0;
|
||||
|
||||
@@ -1083,6 +1096,8 @@ static int hdmi_codec_probe(struct platform_device *pdev)
|
||||
hcp->hcd = *hcd;
|
||||
mutex_init(&hcp->lock);
|
||||
|
||||
hcp->tx_dlp = device_property_read_bool(dev->parent, "audio,digital-loopback");
|
||||
|
||||
ret = snd_pcm_create_iec958_consumer_default(hcp->iec_status,
|
||||
sizeof(hcp->iec_status));
|
||||
if (ret < 0)
|
||||
|
||||
@@ -7,6 +7,13 @@ config SND_SOC_ROCKCHIP
|
||||
the Rockchip SoCs' Audio interfaces. You will also need to
|
||||
select the audio interfaces to support below.
|
||||
|
||||
config SND_SOC_ROCKCHIP_ASRC
|
||||
tristate "Rockchip Asynchronous Sampling Rate Converter Driver"
|
||||
depends on SND_SOC_ROCKCHIP
|
||||
help
|
||||
Say Y or M if you want to add support for ASRC driver for
|
||||
Rockchip.
|
||||
|
||||
config SND_SOC_ROCKCHIP_DLP
|
||||
tristate
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# ROCKCHIP Platform Support
|
||||
snd-soc-rockchip-objs := rockchip_utils.o
|
||||
snd-soc-rockchip-asrc-objs := rockchip_asrc.o
|
||||
snd-soc-rockchip-dlp-objs := rockchip_dlp.o
|
||||
snd-soc-rockchip-dlp-pcm-objs := rockchip_dlp_pcm.o
|
||||
snd-soc-rockchip-i2s-objs := rockchip_i2s.o
|
||||
@@ -21,6 +22,7 @@ snd-soc-rockchip-vad-$(CONFIG_ARM) += vad_preprocess_arm.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_SND_SOC_ROCKCHIP) += snd-soc-rockchip.o
|
||||
obj-$(CONFIG_SND_SOC_ROCKCHIP_ASRC) += snd-soc-rockchip-asrc.o
|
||||
obj-$(CONFIG_SND_SOC_ROCKCHIP_DLP) += snd-soc-rockchip-dlp.o
|
||||
obj-$(CONFIG_SND_SOC_ROCKCHIP_DLP_PCM) += snd-soc-rockchip-dlp-pcm.o
|
||||
obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-rockchip-i2s.o
|
||||
|
||||
1528
sound/soc/rockchip/rockchip_asrc.c
Normal file
1528
sound/soc/rockchip/rockchip_asrc.c
Normal file
File diff suppressed because it is too large
Load Diff
191
sound/soc/rockchip/rockchip_asrc.h
Normal file
191
sound/soc/rockchip/rockchip_asrc.h
Normal file
@@ -0,0 +1,191 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* ALSA SoC Audio Layer - Rockchip ASRC Controller driver
|
||||
*
|
||||
* Copyright (c) 2024 Rockchip Electronics Co. Ltd.
|
||||
*/
|
||||
|
||||
#ifndef _ROCKCHIP_ASRC_H_
|
||||
#define _ROCKCHIP_ASRC_H_
|
||||
|
||||
#define ASRC_VERSION 0x0000
|
||||
#define ASRC_CON 0x0004
|
||||
#define ASRC_CLKDIV_CON 0x0008
|
||||
#define ASRC_DATA_FMT 0x000c
|
||||
#define ASRC_LOOP_CON0 0x0010
|
||||
#define ASRC_LOOP_CON1 0x0014
|
||||
#define ASRC_LOOP_CON2 0x0018
|
||||
#define ASRC_MANUAL_RATIO 0x0020
|
||||
#define ASRC_SAMPLE_RATE 0x0024
|
||||
#define ASRC_RESAMPLE_RATE 0x0028
|
||||
#define ASRC_TRACK_PERIOD 0x002c
|
||||
#define ASRC_RATIO_MARGIN 0x0030
|
||||
#define ASRC_LRCK_MARGIN 0x0034
|
||||
#define ASRC_FETCH_LEN 0x0040
|
||||
#define ASRC_DMA_THRESH 0x0050
|
||||
#define ASRC_INT_CON 0x0060
|
||||
#define ASRC_INT_ST 0x0064
|
||||
#define ASRC_ST 0x0070
|
||||
#define ASRC_RATIO_ST 0x0080
|
||||
#define ASRC_RESAMPLE_RATE_ST 0x0084
|
||||
#define ASRC_THETA_CNT_ST 0x0090
|
||||
#define ASRC_DECI_THETA_ACC_ST 0x0094
|
||||
#define ASRC_FIFO_IN_WRCNT 0x00a0
|
||||
#define ASRC_FIFO_IN_RDCNT 0x00a4
|
||||
#define ASRC_FIFO_OUT_WRCNT 0x00b0
|
||||
#define ASRC_FIFO_OUT_RDCNT 0x00b4
|
||||
#define ASRC_RXDR 0x00c0
|
||||
#define ASRC_TXDR 0x00c4
|
||||
#define ASRC_FIFO_IN_DATA 0x1000
|
||||
#define ASRC_FIFO_OUT_DATA 0x5000
|
||||
|
||||
/**********************ASRC_CON************************/
|
||||
#define ASRC_RATIO_FILT_WIN (0x3 << 20)
|
||||
#define ASRC_RATIO_TRACK_MODE (0x1 << 19)
|
||||
#define ASRC_RATIO_TRACK_MODE_DIS (0x0 << 19)
|
||||
#define ASRC_RATIO_EXC_MSK (0x1 << 18)
|
||||
#define ASRC_RATIO_EXC_EN (0x1 << 18)
|
||||
#define ASRC_RATIO_EXC_DIS (0x0 << 18)
|
||||
#define ASRC_RATIO_FILT_MSK (0x1 << 17)
|
||||
#define ASRC_RATIO_FILT_EN (0x1 << 17)
|
||||
#define ASRC_RATIO_FILT_DIS (0x0 << 17)
|
||||
#define ASRC_RATIO_TRACK_MSK (0x1 << 16)
|
||||
#define ASRC_RATIO_TRACK_EN (0x1 << 16)
|
||||
#define ASRC_RATIO_TRACK_DIS (0x0 << 16)
|
||||
#define ASRC_OUT_MSK (0x1 << 9)
|
||||
#define ASRC_OUT_STOP (0x1 << 9)
|
||||
#define ASRC_OUT_START (0x0 << 9)
|
||||
#define ASRC_IN_MSK (0x1 << 8)
|
||||
#define ASRC_IN_STOP (0x1 << 8)
|
||||
#define ASRC_IN_START (0x0 << 8)
|
||||
#define ASRC_CHAN_NUM_MSK (0x3 << 4)
|
||||
#define ASRC_CHAN_NUM(x) (((x - 2) / 2) << 4)
|
||||
#define ASRC_REAL_TIME_MODE_MSK (0x3 << 2)
|
||||
#define ASRC_M2M (0x0 << 2)
|
||||
#define ASRC_S2M (0x1 << 2)
|
||||
#define ASRC_M2D (0x2 << 2)
|
||||
#define ASRC_S2D (0x3 << 2)
|
||||
#define ASRC_MODE_MSK (0x1 << 1)
|
||||
#define ASRC_REAL_TIME (0x0 << 1)
|
||||
#define ASRC_MEMORY_FETCH (0x1 << 1)
|
||||
#define ASRC_MSK (0x1 << 0)
|
||||
#define ASRC_EN (0x1 << 0)
|
||||
#define ASRC_DIS (0x0 << 0)
|
||||
|
||||
/**********************ASRC_CLKDIV_CON************************/
|
||||
#define ASRC_DST_LRCK_DIV_MSK (0x1 << 31)
|
||||
#define ASRC_DST_LRCK_DIV_EN (0x1 << 31)
|
||||
#define ASRC_DST_LRCK_DIV_DIS (0x0 << 31)
|
||||
#define ASRC_DST_LRCK_DIV_CON_MSK (0x7fff << 16)
|
||||
#define ASRC_DST_LRCK_DIV(x) ((x - 1) << 16)
|
||||
#define ASRC_SRC_LRCK_DIV_MSK (0x1 << 15)
|
||||
#define ASRC_SRC_LRCK_DIV_EN (0x1 << 15)
|
||||
#define ASRC_SRC_LRCK_DIV_DIS (0x0 << 15)
|
||||
#define ASRC_SRC_LRCK_DIV_CON_MSK (0x7fff << 0)
|
||||
#define ASRC_SRC_LRCK_DIV(x) ((x - 1) << 0)
|
||||
|
||||
/**********************ASRC_DATA_FMT************************/
|
||||
#define ASRC_OSJM_MSK (0x1f << 24)
|
||||
#define ASRC_OSJM(x) (x << 24)
|
||||
#define ASRC_ISJM_MSK (0x1f << 16)
|
||||
#define ASRC_ISJM(x) (x << 16)
|
||||
#define ASRC_OFMT_MSK (0x1 << 12)
|
||||
#define ASRC_OFMT_16 (0x1 << 12)
|
||||
#define ASRC_OFMT_32 (0x0 << 12)
|
||||
#define ASRC_IFMT_MSK (0x1 << 8)
|
||||
#define ASRC_IFMT_16 (0x1 << 8)
|
||||
#define ASRC_IFMT_32 (0x0 << 8)
|
||||
#define ASRC_OWL_MSK (0x3 << 4)
|
||||
#define ASRC_OWL_16BIT (0x2 << 4)
|
||||
#define ASRC_OWL_20BIT (0x1 << 4)
|
||||
#define ASRC_OWL_24BIT (0x0 << 4)
|
||||
#define ASRC_IWL_MSK (0x3 << 0)
|
||||
#define ASRC_IWL_16BIT (0x2 << 0)
|
||||
#define ASRC_IWL_20BIT (0x1 << 0)
|
||||
#define ASRC_IWL_24BIT (0x0 << 0)
|
||||
|
||||
/**********************ASRC_TRACK_PERIOD************************/
|
||||
#define ASRC_RATIO_TRACK_DIV_MSK (0xfff << 16)
|
||||
#define ASRC_RATIO_TRACK_DIV(x) (x << 16)
|
||||
#define ASRC_RATIO_TRACK_PERIOD_MSK (0xfff << 0)
|
||||
#define ASRC_RATIO_TRACK_PERIOD(x) (x << 0)
|
||||
|
||||
/**********************ASRC_DMA_THRESH************************/
|
||||
#define ASRC_POS_THRESH_MSK (0x1f << 26)
|
||||
#define ASRC_POS_THRESH(x) (x << 26)
|
||||
#define ASRC_NEG_THRESH_MSK (0x1f << 20)
|
||||
#define ASRC_NEG_THRESH(x) (x << 20)
|
||||
#define ASRC_OUT_THRESH_MSK (0xf << 12)
|
||||
#define ASRC_OUT_THRESH(x) (x << 12)
|
||||
#define ASRC_IN_THRESH_MSK (0xf << 8)
|
||||
#define ASRC_IN_THRESH(x) (x << 8)
|
||||
#define ASRC_DMA_RX_THRESH_MSK (0xf << 4)
|
||||
#define ASRC_DMA_RX_THRESH(x) (x << 4)
|
||||
#define ASRC_DMA_TX_THRESH_MSK (0xf << 0)
|
||||
#define ASRC_DMA_TX_THRESH(x) (x << 0)
|
||||
|
||||
/**********************ASRC_INT_CON************************/
|
||||
#define ASRC_DST_LRCK_UNLOCK_MSK (0x1 << 12)
|
||||
#define ASRC_DST_LRCK_UNLOCK_EN (0x1 << 12)
|
||||
#define ASRC_DST_LRCK_UNLOCK_DIS (0x0 << 12)
|
||||
#define ASRC_SRC_LRCK_UNLOCK_MSK (0x1 << 11)
|
||||
#define ASRC_SRC_LRCK_UNLOCK_EN (0x1 << 11)
|
||||
#define ASRC_SRC_LRCK_UNLOCK_DIS (0x0 << 11)
|
||||
#define ASRC_RATIO_UNLOCK_MSK (0x1 << 10)
|
||||
#define ASRC_RATIO_UNLOCK_EN (0x1 << 10)
|
||||
#define ASRC_RATIO_UNLOCK_DIS (0x0 << 10)
|
||||
#define ASRC_FIFO_OUT_EMPTY_MSK (0x1 << 9)
|
||||
#define ASRC_FIFO_OUT_EMPTY_EN (0x1 << 9)
|
||||
#define ASRC_FIFO_OUT_EMPTY_DIS (0x0 << 9)
|
||||
#define ASRC_FIFO_OUT_FULL_MSK (0x1 << 8)
|
||||
#define ASRC_FIFO_OUT_FULL_EN (0x1 << 8)
|
||||
#define ASRC_FIFO_OUT_FULL_DIS (0x0 << 8)
|
||||
#define ASRC_FIFO_IN_EMPTY_MSK (0x1 << 7)
|
||||
#define ASRC_FIFO_IN_EMPTY_EN (0x1 << 7)
|
||||
#define ASRC_FIFO_IN_EMPTY_DIS (0x0 << 7)
|
||||
#define ASRC_FIFO_IN_FULL_MSK (0x1 << 6)
|
||||
#define ASRC_FIFO_IN_FULL_EN (0x1 << 6)
|
||||
#define ASRC_FIFO_IN_FULL_DIS (0x1 << 6)
|
||||
#define ASRC_RATIO_UPDATE_DONE_MSK (0x1 << 5)
|
||||
#define ASRC_RATIO_UPDATE_DONE_EN (0x1 << 5)
|
||||
#define ASRC_RATIO_UPDATE_DONE_DIS (0x0 << 5)
|
||||
#define ASRC_RATIO_CHANGE_DONE_MSK (0x1 << 4)
|
||||
#define ASRC_RATIO_CHANGE_DONE_EN (0x1 << 4)
|
||||
#define ASRC_RATIO_CHANGE_DONE_DIS (0x0 << 4)
|
||||
#define ASRC_RATIO_INIT_DONE_MSK (0x1 << 3)
|
||||
#define ASRC_RATIO_INIT_DONE_EN (0x1 << 3)
|
||||
#define ASRC_RATIO_INIT_DONE_DIS (0x0 << 3)
|
||||
#define ASRC_CONV_ERROR_MSK (0x1 << 2)
|
||||
#define ASRC_CONV_ERROR_EN (0x1 << 2)
|
||||
#define ASRC_CONV_ERROR_DIS (0x0 << 2)
|
||||
#define ASRC_CONV_DONE_MSK (0x1 << 1)
|
||||
#define ASRC_CONV_DONE_EN (0x1 << 1)
|
||||
#define ASRC_CONV_DONE_DIS (0x0 << 0)
|
||||
#define ASRC_OUT_START_MSK (0x1 << 0)
|
||||
#define ASRC_OUT_START_EN (0x1 << 0)
|
||||
#define ASRC_OUT_START_DIS (0x0 << 0)
|
||||
|
||||
/**********************ASRC_INT_ST************************/
|
||||
#define ASRC_DST_LRCK_UNLOCK_ST (0x1 << 12)
|
||||
#define ASRC_SRC_LRCK_UNLOCK_ST (0x1 << 11)
|
||||
#define ASRC_RATIO_UNLOCK_ST (0x1 << 10)
|
||||
#define ASRC_FIFO_OUT_EMPTY_ST (0x1 << 9)
|
||||
#define ASRC_FIFO_OUT_FULL_ST (0x1 << 8)
|
||||
#define ASRC_FIFO_IN_EMPTY_ST (0x1 << 7)
|
||||
#define ASRC_FIFO_IN_FULL_ST (0x1 << 6)
|
||||
#define ASRC_RATIO_UPDATE_DONE_ST (0x1 << 5)
|
||||
#define ASRC_RATIO_CHANGE_DONE_ST (0x1 << 4)
|
||||
#define ASRC_RATIO_INIT_DONE_ST (0x1 << 3)
|
||||
#define ASRC_CONV_ERROR_ST (0x1 << 2)
|
||||
#define ASRC_CONV_DONE_ST (0x1 << 1)
|
||||
#define ASRC_OUT_START_ST (0x1 << 0)
|
||||
|
||||
/**********************ASRC_ST************************/
|
||||
#define ASRC_RATIO_ST_MSK (0x3 << 29)
|
||||
#define ASRC_RATIO_ST_INIT (0x0 << 29)
|
||||
#define ASRC_RATIO_ST_TRACK (0x1 << 29)
|
||||
#define ASRC_RATIO_ST_STOP (0x2 << 29)
|
||||
#define ASRC_EXCEED_POS (0x1 << 28)
|
||||
#define ASRC_EXCEED_NEG (0x1 << 27)
|
||||
|
||||
#endif
|
||||
@@ -181,6 +181,25 @@ static struct i2s_of_quirks {
|
||||
},
|
||||
};
|
||||
|
||||
static bool rockchip_i2s_tdm_stream_valid(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (!substream)
|
||||
return false;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
|
||||
i2s_tdm->has_playback)
|
||||
return true;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
|
||||
i2s_tdm->has_capture)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int to_ch_num(unsigned int val)
|
||||
{
|
||||
switch (val) {
|
||||
@@ -1024,6 +1043,9 @@ static void rockchip_i2s_tdm_xfer_stop(struct rk_i2s_tdm_dev *i2s_tdm,
|
||||
udelay(150);
|
||||
|
||||
rockchip_i2s_tdm_clear(i2s_tdm, clr);
|
||||
|
||||
dev_dbg(i2s_tdm->dev, "%s: stream: %d force: %d\n",
|
||||
__func__, stream, force);
|
||||
}
|
||||
|
||||
static void rockchip_i2s_tdm_xfer_trcm_start(struct rk_i2s_tdm_dev *i2s_tdm,
|
||||
@@ -1370,6 +1392,7 @@ static int rockchip_i2s_tdm_set_fmt(struct snd_soc_dai *cpu_dai,
|
||||
}
|
||||
|
||||
val = ret;
|
||||
ret = 0;
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_TXCR, mask, val);
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_RXCR, mask, val);
|
||||
}
|
||||
@@ -1679,8 +1702,20 @@ static bool is_params_dirty(struct snd_pcm_substream *substream,
|
||||
if (last_div_bclk != div_bclk)
|
||||
return true;
|
||||
|
||||
regmap_read(i2s_tdm->regmap, I2S_CKR, &val);
|
||||
last_div_lrck = ((val & I2S_CKR_TSD_MASK) >> I2S_CKR_TSD_SHIFT) + 1;
|
||||
if (i2s_tdm->tdm_mode) {
|
||||
regmap_read(i2s_tdm->regmap,
|
||||
substream->stream ? I2S_TDM_RXCR : I2S_TDM_TXCR, &val);
|
||||
last_div_lrck = TDM_FRAME_WIDTH_V(val);
|
||||
|
||||
regmap_read(i2s_tdm->regmap,
|
||||
substream->stream ? I2S_RXCR : I2S_TXCR, &val);
|
||||
val &= I2S_TXCR_TFS_MASK;
|
||||
if (val == I2S_TXCR_TFS_TDM_I2S && !i2s_tdm->tdm_fsync_half_frame)
|
||||
last_div_lrck <<= 1;
|
||||
} else {
|
||||
regmap_read(i2s_tdm->regmap, I2S_CKR, &val);
|
||||
last_div_lrck = I2S_CKR_TSD_V(val);
|
||||
}
|
||||
if (last_div_lrck != div_lrck)
|
||||
return true;
|
||||
|
||||
@@ -1827,6 +1862,9 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
|
||||
unsigned int val = 0;
|
||||
unsigned int mclk_rate, bclk_rate, lrck_rate, div_bclk = 4, div_lrck = 64;
|
||||
|
||||
if (!rockchip_i2s_tdm_stream_valid(substream, dai))
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_SND_SOC_ROCKCHIP_I2S_TDM_MULTI_LANES
|
||||
if (i2s_tdm->is_tdm_multi_lanes)
|
||||
rockchip_i2s_tdm_multi_lanes_set_clk(substream, params, dai);
|
||||
@@ -1892,6 +1930,9 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
|
||||
static int rockchip_i2s_tdm_hw_free(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
if (!rockchip_i2s_tdm_stream_valid(substream, dai))
|
||||
return 0;
|
||||
|
||||
rockchip_utils_put_performance(substream, dai);
|
||||
|
||||
return 0;
|
||||
@@ -1902,6 +1943,9 @@ static int rockchip_i2s_tdm_trigger(struct snd_pcm_substream *substream,
|
||||
{
|
||||
struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
|
||||
|
||||
if (!rockchip_i2s_tdm_stream_valid(substream, dai))
|
||||
return 0;
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
@@ -2248,6 +2292,24 @@ static int rockchip_dai_tdm_slot(struct snd_soc_dai *dai,
|
||||
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_TXCR, mask, val);
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_RXCR, mask, val);
|
||||
/*
|
||||
* TDM mode use all FIFOs, the max burst is 16 word of DMAC,
|
||||
* so we used the max FIFO to cover DDR dmc windows.
|
||||
*
|
||||
* 4 FIFOs controller:
|
||||
*
|
||||
* TDL:
|
||||
*
|
||||
* 16 word: WL = ((32 * 4) - 16) / 4 = 28
|
||||
*
|
||||
* RDL:
|
||||
*
|
||||
* 16 word: WL = 16 / 4 = 4
|
||||
*/
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,
|
||||
I2S_DMACR_TDL(28));
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK,
|
||||
I2S_DMACR_RDL(4));
|
||||
|
||||
pm_runtime_put(dai->dev);
|
||||
|
||||
@@ -2273,6 +2335,9 @@ static int rockchip_i2s_tdm_startup(struct snd_pcm_substream *substream,
|
||||
struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
|
||||
int stream = substream->stream;
|
||||
|
||||
if (!rockchip_i2s_tdm_stream_valid(substream, dai))
|
||||
return 0;
|
||||
|
||||
if (i2s_tdm->substreams[stream])
|
||||
return -EBUSY;
|
||||
|
||||
@@ -2289,6 +2354,9 @@ static void rockchip_i2s_tdm_shutdown(struct snd_pcm_substream *substream,
|
||||
{
|
||||
struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (!rockchip_i2s_tdm_stream_valid(substream, dai))
|
||||
return;
|
||||
|
||||
i2s_tdm->substreams[substream->stream] = NULL;
|
||||
}
|
||||
|
||||
@@ -2825,6 +2893,9 @@ static int rockchip_i2s_tdm_keep_clk_always_on(struct rk_i2s_tdm_dev *i2s_tdm)
|
||||
unsigned int div_bclk;
|
||||
int ret;
|
||||
|
||||
if (mclk_rate < bclk_rate)
|
||||
mclk_rate = bclk_rate;
|
||||
|
||||
div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate);
|
||||
|
||||
/* assign generic freq */
|
||||
|
||||
@@ -118,6 +118,7 @@
|
||||
#define I2S_CKR_RSD_MASK (0xff << I2S_CKR_RSD_SHIFT)
|
||||
#define I2S_CKR_TSD_SHIFT 0
|
||||
#define I2S_CKR_TSD(x) (((x) - 1) << I2S_CKR_TSD_SHIFT)
|
||||
#define I2S_CKR_TSD_V(x) ((((x) & I2S_CKR_TSD_MASK) >> I2S_CKR_TSD_SHIFT) + 1)
|
||||
#define I2S_CKR_TSD_MASK (0xff << I2S_CKR_TSD_SHIFT)
|
||||
|
||||
/*
|
||||
@@ -269,6 +270,7 @@
|
||||
#define TDM_SLOT_BIT_WIDTH(x) (((x) - 1) << 9)
|
||||
#define TDM_FRAME_WIDTH_MSK GENMASK(8, 0)
|
||||
#define TDM_FRAME_WIDTH(x) (((x) - 1) << 0)
|
||||
#define TDM_FRAME_WIDTH_V(v) ((((v) & TDM_FRAME_WIDTH_MSK) >> 0) + 1)
|
||||
|
||||
/*
|
||||
* CLKDIV
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#define DRV_NAME "rk-multicodecs"
|
||||
#define WAIT_CARDS (SNDRV_CARDS - 1)
|
||||
#define DEFAULT_MCLK_FS 256
|
||||
#define DAI_FMT_BASE (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF)
|
||||
|
||||
struct adc_keys_button {
|
||||
u32 voltage;
|
||||
@@ -57,7 +58,7 @@ struct input_dev_poller {
|
||||
|
||||
struct multicodecs_data {
|
||||
struct snd_soc_card snd_card;
|
||||
struct snd_soc_dai_link dai_link;
|
||||
struct snd_soc_dai_link dai_link[3];
|
||||
struct snd_soc_jack *jack_headset;
|
||||
struct gpio_desc *hp_ctl_gpio;
|
||||
struct gpio_desc *spk_ctl_gpio;
|
||||
@@ -312,7 +313,6 @@ static int mc_spk_event(struct snd_soc_dapm_widget *w,
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -321,6 +321,8 @@ static int mc_spk_event(struct snd_soc_dapm_widget *w,
|
||||
static const struct snd_soc_dapm_widget mc_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_HP("Headphone", mc_hp_event),
|
||||
SND_SOC_DAPM_SPK("Speaker", mc_spk_event),
|
||||
SND_SOC_DAPM_LINE("Line Out Jack", NULL),
|
||||
SND_SOC_DAPM_LINE("Line In Jack", NULL),
|
||||
SND_SOC_DAPM_MIC("Main Mic", NULL),
|
||||
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
||||
SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||
@@ -492,7 +494,7 @@ static int rk_multicodecs_parse_daifmt(struct device_node *node,
|
||||
struct multicodecs_data *mc_data,
|
||||
const char *prefix)
|
||||
{
|
||||
struct snd_soc_dai_link *dai_link = &mc_data->dai_link;
|
||||
struct snd_soc_dai_link *dai_link = &mc_data->dai_link[0];
|
||||
struct device_node *bitclkmaster = NULL;
|
||||
struct device_node *framemaster = NULL;
|
||||
unsigned int daifmt;
|
||||
@@ -592,17 +594,56 @@ static struct snd_soc_ops rk_ops = {
|
||||
.hw_params = rk_multicodecs_hw_params,
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEFS(hifi,
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(hifi_fe,
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()),
|
||||
DAILINK_COMP_ARRAY(COMP_DUMMY()),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(hifi_be,
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()),
|
||||
DAILINK_COMP_ARRAY(COMP_DUMMY()));
|
||||
|
||||
static const struct snd_soc_dai_link rk_multicodecs_card_dai[] = {
|
||||
/* Default ASoC DAI Link*/
|
||||
{
|
||||
.name = "HiFi",
|
||||
.stream_name = "HiFi",
|
||||
.ops = &rk_ops,
|
||||
SND_SOC_DAILINK_REG(hifi),
|
||||
},
|
||||
/* DPCM Link between Front-End and Back-End (Optional) */
|
||||
{
|
||||
.name = "HiFi-ASRC-FE",
|
||||
.stream_name = "HiFi-ASRC-FE",
|
||||
.dpcm_playback = 1,
|
||||
.dpcm_capture = 1,
|
||||
.dynamic = 1,
|
||||
SND_SOC_DAILINK_REG(hifi_fe),
|
||||
},
|
||||
{
|
||||
.name = "HiFi-ASRC-BE",
|
||||
.stream_name = "HiFi-ASRC-BE",
|
||||
.ops = &rk_ops,
|
||||
.dpcm_playback = 1,
|
||||
.dpcm_capture = 1,
|
||||
.no_pcm = 1,
|
||||
SND_SOC_DAILINK_REG(hifi_be),
|
||||
},
|
||||
};
|
||||
|
||||
static int rk_multicodecs_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct snd_soc_dai_link *link;
|
||||
struct snd_soc_dai_link_component *cpus;
|
||||
struct snd_soc_dai_link_component *platforms;
|
||||
struct device_node *np = pdev->dev.of_node, *node, *asrc_np;
|
||||
struct snd_soc_dai_link_component *codecs;
|
||||
struct multicodecs_data *mc_data;
|
||||
struct of_phandle_args args;
|
||||
struct device_node *node;
|
||||
struct input_dev *input;
|
||||
u32 val;
|
||||
int count, value, irq;
|
||||
@@ -619,13 +660,7 @@ static int rk_multicodecs_probe(struct platform_device *pdev)
|
||||
if (!mc_data)
|
||||
return -ENOMEM;
|
||||
|
||||
cpus = devm_kzalloc(&pdev->dev, sizeof(*cpus), GFP_KERNEL);
|
||||
if (!cpus)
|
||||
return -ENOMEM;
|
||||
|
||||
platforms = devm_kzalloc(&pdev->dev, sizeof(*platforms), GFP_KERNEL);
|
||||
if (!platforms)
|
||||
return -ENOMEM;
|
||||
memcpy(mc_data->dai_link, rk_multicodecs_card_dai, sizeof(mc_data->dai_link));
|
||||
|
||||
card = &mc_data->snd_card;
|
||||
card->dev = &pdev->dev;
|
||||
@@ -635,18 +670,15 @@ static int rk_multicodecs_probe(struct platform_device *pdev)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
link = &mc_data->dai_link;
|
||||
link->name = "dailink-multicodecs";
|
||||
link->stream_name = link->name;
|
||||
link->init = rk_dailink_init;
|
||||
link->ops = &rk_ops;
|
||||
link->cpus = cpus;
|
||||
link->platforms = platforms;
|
||||
link->num_cpus = 1;
|
||||
link->num_platforms = 1;
|
||||
link->ignore_pmdown_time = 1;
|
||||
mc_data->dai_link[0].name = "dailink-multicodecs";
|
||||
mc_data->dai_link[0].stream_name = mc_data->dai_link[0].name;
|
||||
mc_data->dai_link[0].init = rk_dailink_init;
|
||||
mc_data->dai_link[0].ops = &rk_ops;
|
||||
mc_data->dai_link[0].num_cpus = 1;
|
||||
mc_data->dai_link[0].num_platforms = 1;
|
||||
mc_data->dai_link[0].ignore_pmdown_time = 1;
|
||||
|
||||
card->dai_link = link;
|
||||
card->dai_link = mc_data->dai_link;
|
||||
card->num_links = 1;
|
||||
card->dapm_widgets = mc_dapm_widgets;
|
||||
card->num_dapm_widgets = ARRAY_SIZE(mc_dapm_widgets);
|
||||
@@ -675,8 +707,8 @@ static int rk_multicodecs_probe(struct platform_device *pdev)
|
||||
if (!codecs)
|
||||
return -ENOMEM;
|
||||
|
||||
link->codecs = codecs;
|
||||
link->num_codecs = idx;
|
||||
mc_data->dai_link[0].codecs = codecs;
|
||||
mc_data->dai_link[0].num_codecs = idx;
|
||||
idx = 0;
|
||||
for (i = 0; i < count; i++) {
|
||||
node = of_parse_phandle(np, "rockchip,codec", i);
|
||||
@@ -700,11 +732,26 @@ static int rk_multicodecs_probe(struct platform_device *pdev)
|
||||
/* Only reference the codecs[0].of_node which maybe as master. */
|
||||
rk_multicodecs_parse_daifmt(np, codecs[0].of_node, mc_data, prefix);
|
||||
|
||||
link->cpus->of_node = of_parse_phandle(np, "rockchip,cpu", 0);
|
||||
if (!link->cpus->of_node)
|
||||
mc_data->dai_link[0].cpus->of_node = of_parse_phandle(np, "rockchip,cpu", 0);
|
||||
if (!mc_data->dai_link[0].cpus->of_node)
|
||||
return -ENODEV;
|
||||
|
||||
link->platforms->of_node = link->cpus->of_node;
|
||||
mc_data->dai_link[0].platforms->of_node = mc_data->dai_link[0].cpus->of_node;
|
||||
|
||||
asrc_np = of_parse_phandle(np, "rockchip,asrc", 0);
|
||||
if (asrc_np) {
|
||||
mc_data->dai_link[1].cpus->of_node = asrc_np;
|
||||
mc_data->dai_link[1].platforms->of_node = asrc_np;
|
||||
mc_data->dai_link[1].num_cpus = 1;
|
||||
mc_data->dai_link[1].num_platforms = 1;
|
||||
|
||||
/* Support multicodec in future */
|
||||
mc_data->dai_link[2].codecs->dai_name = "dummy_codec";
|
||||
mc_data->dai_link[2].codecs->of_node = of_parse_phandle(np, "rockchip,codec", 0);
|
||||
mc_data->dai_link[2].cpus->of_node = mc_data->dai_link[0].cpus->of_node;
|
||||
|
||||
card->num_links = 3;
|
||||
}
|
||||
|
||||
mc_data->mclk_fs = DEFAULT_MCLK_FS;
|
||||
if (!of_property_read_u32(np, "rockchip,mclk-fs", &val))
|
||||
@@ -814,7 +861,7 @@ static int rk_multicodecs_probe(struct platform_device *pdev)
|
||||
snd_soc_of_parse_audio_routing(card, "rockchip,audio-routing");
|
||||
|
||||
snd_soc_card_set_drvdata(card, mc_data);
|
||||
platform_set_drvdata(pdev, card);
|
||||
platform_set_drvdata(pdev, mc_data);
|
||||
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||
if (ret) {
|
||||
@@ -832,8 +879,7 @@ static int rk_multicodecs_probe(struct platform_device *pdev)
|
||||
|
||||
static int rk_multicodec_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = platform_get_drvdata(pdev);
|
||||
struct multicodecs_data *mc_data = snd_soc_card_get_drvdata(card);
|
||||
struct multicodecs_data *mc_data = platform_get_drvdata(pdev);
|
||||
|
||||
cancel_delayed_work_sync(&mc_data->handler);
|
||||
|
||||
@@ -842,8 +888,7 @@ static int rk_multicodec_remove(struct platform_device *pdev)
|
||||
|
||||
static void rk_multicodec_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = platform_get_drvdata(pdev);
|
||||
struct multicodecs_data *mc_data = snd_soc_card_get_drvdata(card);
|
||||
struct multicodecs_data *mc_data = platform_get_drvdata(pdev);
|
||||
|
||||
cancel_delayed_work_sync(&mc_data->handler);
|
||||
}
|
||||
|
||||
@@ -87,6 +87,25 @@ static const struct sai_of_quirks {
|
||||
},
|
||||
};
|
||||
|
||||
static bool rockchip_sai_stream_valid(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct rk_sai_dev *sai = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (!substream)
|
||||
return false;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
|
||||
sai->has_playback)
|
||||
return true;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
|
||||
sai->has_capture)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int rockchip_sai_fsync_lost_detect(struct rk_sai_dev *sai, bool en)
|
||||
{
|
||||
unsigned int fw, cnt;
|
||||
@@ -524,6 +543,9 @@ static int rockchip_sai_hw_params(struct snd_pcm_substream *substream,
|
||||
unsigned int ch_per_lane, lanes, slot_width;
|
||||
unsigned int val, fscr, reg, fifo;
|
||||
|
||||
if (!rockchip_sai_stream_valid(substream, dai))
|
||||
return 0;
|
||||
|
||||
dma_data = snd_soc_dai_get_dma_data(dai, substream);
|
||||
dma_data->maxburst = MAXBURST_PER_FIFO * params_channels(params) / 2;
|
||||
|
||||
@@ -621,6 +643,9 @@ static int rockchip_sai_hw_params(struct snd_pcm_substream *substream,
|
||||
static int rockchip_sai_hw_free(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
if (!rockchip_sai_stream_valid(substream, dai))
|
||||
return 0;
|
||||
|
||||
rockchip_utils_put_performance(substream, dai);
|
||||
|
||||
return 0;
|
||||
@@ -631,6 +656,9 @@ static int rockchip_sai_prepare(struct snd_pcm_substream *substream,
|
||||
{
|
||||
struct rk_sai_dev *sai = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (!rockchip_sai_stream_valid(substream, dai))
|
||||
return 0;
|
||||
|
||||
if (sai->is_master_mode) {
|
||||
/*
|
||||
* Should wait for one BCLK ready after DIV and then ungate
|
||||
@@ -760,6 +788,9 @@ static int rockchip_sai_trigger(struct snd_pcm_substream *substream,
|
||||
struct rk_sai_dev *sai = snd_soc_dai_get_drvdata(dai);
|
||||
int ret = 0;
|
||||
|
||||
if (!rockchip_sai_stream_valid(substream, dai))
|
||||
return 0;
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
@@ -934,6 +965,9 @@ static int rockchip_sai_startup(struct snd_pcm_substream *substream,
|
||||
struct rk_sai_dev *sai = snd_soc_dai_get_drvdata(dai);
|
||||
int stream = substream->stream;
|
||||
|
||||
if (!rockchip_sai_stream_valid(substream, dai))
|
||||
return 0;
|
||||
|
||||
if (sai->substreams[stream])
|
||||
return -EBUSY;
|
||||
|
||||
@@ -950,6 +984,9 @@ static void rockchip_sai_shutdown(struct snd_pcm_substream *substream,
|
||||
{
|
||||
struct rk_sai_dev *sai = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (!rockchip_sai_stream_valid(substream, dai))
|
||||
return;
|
||||
|
||||
sai->substreams[substream->stream] = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -303,6 +303,11 @@ static int dmaengine_trcm_trigger(struct snd_soc_component *component,
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
int ret;
|
||||
|
||||
#ifdef TRCM_DEBUG
|
||||
ktime_t start_time, stop_time, diff_time;
|
||||
|
||||
start_time = ktime_get();
|
||||
#endif
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
dmaengine_terminate_async(prtd->dma_chan);
|
||||
@@ -332,6 +337,13 @@ static int dmaengine_trcm_trigger(struct snd_soc_component *component,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef TRCM_DEBUG
|
||||
stop_time = ktime_get();
|
||||
diff_time = ktime_sub(stop_time, start_time);
|
||||
dev_dbg(component->dev, "cmd: %d time cost %lld\n",
|
||||
cmd, ktime_to_us(diff_time));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user