diff --git a/sound/soc/tegra/tegra210_i2s.c b/sound/soc/tegra/tegra210_i2s.c index 8448cfb7..1cb01be7 100644 --- a/sound/soc/tegra/tegra210_i2s.c +++ b/sound/soc/tegra/tegra210_i2s.c @@ -2,7 +2,7 @@ // // tegra210_i2s.c - Tegra210 I2S driver // -// Copyright (c) 2020-2021 NVIDIA CORPORATION. All rights reserved. +// Copyright (c) 2020 NVIDIA CORPORATION. All rights reserved. #include #include @@ -17,12 +17,6 @@ #include "tegra210_i2s.h" #include "tegra_cif.h" -#if IS_ENABLED(CONFIG_TEGRA_DPCM) -#define TEGRA_PLAYBACK_STREAM SNDRV_PCM_STREAM_PLAYBACK -#else -#define TEGRA_PLAYBACK_STREAM SNDRV_PCM_STREAM_CAPTURE -#endif - static const struct reg_default tegra210_i2s_reg_defaults[] = { { TEGRA210_I2S_RX_INT_MASK, 0x00000003 }, { TEGRA210_I2S_RX_CIF_CTRL, 0x00007700 }, @@ -323,38 +317,27 @@ static int tegra210_i2s_get_control(struct snd_kcontrol *kcontrol, { struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); - long *uctl_val = &ucontrol->value.integer.value[0]; if (strstr(kcontrol->id.name, "Loopback")) - *uctl_val = i2s->loopback; - else if (strstr(kcontrol->id.name, "Sample Rate")) - *uctl_val = i2s->srate_override; - else if (strstr(kcontrol->id.name, "Playback Audio Bit Format")) - *uctl_val = i2s->audio_fmt_override[I2S_RX_PATH]; - else if (strstr(kcontrol->id.name, "Capture Audio Bit Format")) - *uctl_val = i2s->audio_fmt_override[I2S_TX_PATH]; - else if (strstr(kcontrol->id.name, "Client Bit Format")) - *uctl_val = i2s->client_fmt_override; - else if (strstr(kcontrol->id.name, "Playback Audio Channels")) - *uctl_val = i2s->audio_ch_override[I2S_RX_PATH]; - else if (strstr(kcontrol->id.name, "Capture Audio Channels")) - *uctl_val = i2s->audio_ch_override[I2S_TX_PATH]; - else if (strstr(kcontrol->id.name, "Client Channels")) - *uctl_val = i2s->client_ch_override; + ucontrol->value.integer.value[0] = i2s->loopback; else if (strstr(kcontrol->id.name, "FSYNC Width")) - *uctl_val = i2s->fsync_width; + ucontrol->value.integer.value[0] = i2s->fsync_width; else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) - *uctl_val = i2s->stereo_to_mono[I2S_TX_PATH]; + ucontrol->value.enumerated.item[0] = + i2s->stereo_to_mono[I2S_TX_PATH]; else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) - *uctl_val = i2s->mono_to_stereo[I2S_TX_PATH]; + ucontrol->value.enumerated.item[0] = + i2s->mono_to_stereo[I2S_TX_PATH]; else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) - *uctl_val = i2s->stereo_to_mono[I2S_RX_PATH]; + ucontrol->value.enumerated.item[0] = + i2s->stereo_to_mono[I2S_RX_PATH]; else if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) - *uctl_val = i2s->mono_to_stereo[I2S_RX_PATH]; + ucontrol->value.enumerated.item[0] = + i2s->mono_to_stereo[I2S_RX_PATH]; else if (strstr(kcontrol->id.name, "Playback FIFO Threshold")) - *uctl_val = i2s->rx_fifo_th; + ucontrol->value.integer.value[0] = i2s->rx_fifo_th; else if (strstr(kcontrol->id.name, "BCLK Ratio")) - *uctl_val = i2s->bclk_ratio; + ucontrol->value.integer.value[0] = i2s->bclk_ratio; return 0; } @@ -364,17 +347,14 @@ static int tegra210_i2s_put_control(struct snd_kcontrol *kcontrol, { struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); - int value = ucontrol->value.integer.value[0]; if (strstr(kcontrol->id.name, "Loopback")) { - i2s->loopback = value; + i2s->loopback = ucontrol->value.integer.value[0]; regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, I2S_CTRL_LPBK_MASK, i2s->loopback << I2S_CTRL_LPBK_SHIFT); - } else if (strstr(kcontrol->id.name, "Sample Rate")) { - i2s->srate_override = value; } else if (strstr(kcontrol->id.name, "FSYNC Width")) { /* * Frame sync width is used only for FSYNC modes and not @@ -384,69 +364,33 @@ static int tegra210_i2s_put_control(struct snd_kcontrol *kcontrol, * cases mixer control is used to update custom values. A value * of "N" here means, width is "N + 1" bit clock wide. */ - i2s->fsync_width = value; + i2s->fsync_width = ucontrol->value.integer.value[0]; regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, I2S_CTRL_FSYNC_WIDTH_MASK, i2s->fsync_width << I2S_FSYNC_WIDTH_SHIFT); - } else if (strstr(kcontrol->id.name, "Playback Audio Bit Format")) { - i2s->audio_fmt_override[I2S_RX_PATH] = value; - } else if (strstr(kcontrol->id.name, "Capture Audio Bit Format")) { - i2s->audio_fmt_override[I2S_TX_PATH] = value; - } else if (strstr(kcontrol->id.name, "Client Bit Format")) { - i2s->client_fmt_override = value; - } else if (strstr(kcontrol->id.name, "Playback Audio Channels")) { - i2s->audio_ch_override[I2S_RX_PATH] = value; - } else if (strstr(kcontrol->id.name, "Capture Audio Channels")) { - i2s->audio_ch_override[I2S_TX_PATH] = value; - } else if (strstr(kcontrol->id.name, "Client Channels")) { - i2s->client_ch_override = value; } else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) { - i2s->stereo_to_mono[I2S_TX_PATH] = value; + i2s->stereo_to_mono[I2S_TX_PATH] = + ucontrol->value.enumerated.item[0]; } else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) { - i2s->mono_to_stereo[I2S_TX_PATH] = value; + i2s->mono_to_stereo[I2S_TX_PATH] = + ucontrol->value.enumerated.item[0]; } else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) { - i2s->stereo_to_mono[I2S_RX_PATH] = value; + i2s->stereo_to_mono[I2S_RX_PATH] = + ucontrol->value.enumerated.item[0]; } else if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) { - i2s->mono_to_stereo[I2S_RX_PATH] = value; + i2s->mono_to_stereo[I2S_RX_PATH] = + ucontrol->value.enumerated.item[0]; } else if (strstr(kcontrol->id.name, "Playback FIFO Threshold")) { - i2s->rx_fifo_th = value; + i2s->rx_fifo_th = ucontrol->value.integer.value[0]; } else if (strstr(kcontrol->id.name, "BCLK Ratio")) { - i2s->bclk_ratio = value; + i2s->bclk_ratio = ucontrol->value.integer.value[0]; } return 0; } -static const char * const tegra210_i2s_format_text[] = { - "None", - "16", - "32", -}; - -static const unsigned int tegra210_cif_fmt[] = { - 0, - TEGRA_ACIF_BITS_16, - TEGRA_ACIF_BITS_32, -}; - -static const unsigned int tegra210_i2s_bit_fmt[] = { - 0, - I2S_BITS_16, - I2S_BITS_32, -}; - -static const unsigned int tegra210_i2s_sample_size[] = { - 0, - 16, - 32, -}; - -static const struct soc_enum tegra210_i2s_format_enum = - SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(tegra210_i2s_format_text), - tegra210_i2s_format_text); - static int tegra210_i2s_set_timing_params(struct device *dev, unsigned int sample_size, unsigned int srate, @@ -541,22 +485,6 @@ static int tegra210_i2s_hw_params(struct snd_pcm_substream *substream, cif_conf.audio_bits = TEGRA_ACIF_BITS_16; cif_conf.client_bits = TEGRA_ACIF_BITS_16; break; - case SNDRV_PCM_FORMAT_S24_LE: - val = I2S_BITS_24; - - /* - * I2S bit clock is derived from PLLA_OUT0 and size of - * 24 bits results in fractional value and the clock - * is not accurate with this. To have integer clock - * division below is used. It means there are additional - * bit clocks (8 cycles) which are ignored. Codec picks - * up data for other channel when LRCK signal toggles. - */ - sample_size = 32; - - cif_conf.audio_bits = TEGRA_ACIF_BITS_32; - cif_conf.client_bits = TEGRA_ACIF_BITS_24; - break; case SNDRV_PCM_FORMAT_S32_LE: val = I2S_BITS_32; sample_size = 32; @@ -568,41 +496,19 @@ static int tegra210_i2s_hw_params(struct snd_pcm_substream *substream, return -EOPNOTSUPP; } - if (i2s->client_fmt_override) { - val = tegra210_i2s_bit_fmt[i2s->client_fmt_override]; - sample_size = - tegra210_i2s_sample_size[i2s->client_fmt_override]; - cif_conf.client_bits = - tegra210_cif_fmt[i2s->client_fmt_override]; - } - /* Program sample size */ regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, I2S_CTRL_BIT_SIZE_MASK, val); srate = params_rate(params); - /* Override rate, channel and audio bit params as applicable */ - if (i2s->srate_override) - srate = i2s->srate_override; - - if (i2s->audio_ch_override[path]) - cif_conf.audio_ch = i2s->audio_ch_override[path]; - - if (i2s->client_ch_override) - cif_conf.client_ch = i2s->client_ch_override; - - if (i2s->audio_fmt_override[path]) - cif_conf.audio_bits = - tegra210_cif_fmt[i2s->audio_fmt_override[path]]; - /* For playback I2S RX-CIF and for capture TX-CIF is used */ - if (substream->stream == TEGRA_PLAYBACK_STREAM) + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) path = I2S_RX_PATH; else path = I2S_TX_PATH; - if (substream->stream == TEGRA_PLAYBACK_STREAM) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { unsigned int max_th; /* FIFO threshold in terms of frames */ @@ -634,87 +540,51 @@ static const struct snd_soc_dai_ops tegra210_i2s_dai_ops = { .set_tdm_slot = tegra210_i2s_set_tdm_slot, }; -/* - * Three DAIs are exposed - * 1. "CIF" DAI for connecting with XBAR - * 2. "DAP" DAI for connecting with CODEC - * 3. "DUMMY" can be used when no external codec connection is - * available. In such case "DAP" is connected with "DUMMY". - * Order of these DAIs should not be changed, since DAI links in DT refer - * to these DAIs depending on the index. - */ static struct snd_soc_dai_driver tegra210_i2s_dais[] = { - { - .name = "I2S-CIF", - .playback = { - .stream_name = "CIF-Playback", - .channels_min = 1, - .channels_max = 16, - .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S32_LE, - }, - .capture = { - .stream_name = "CIF-Capture", - .channels_min = 1, - .channels_max = 16, - .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S32_LE, - }, - }, { - .name = "I2S-DAP", - .playback = { - .stream_name = "DAP-Playback", - .channels_min = 1, - .channels_max = 16, - .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S32_LE, - }, - .capture = { - .stream_name = "DAP-Capture", - .channels_min = 1, - .channels_max = 16, - .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S32_LE, - }, - .ops = &tegra210_i2s_dai_ops, - .symmetric_rates = 1, - }, + .name = "I2S-CIF", + .playback = { + .stream_name = "CIF-Playback", + .channels_min = 1, + .channels_max = 16, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .capture = { + .stream_name = "CIF-Capture", + .channels_min = 1, + .channels_max = 16, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + }, { - .name = "DUMMY", - .playback = { - .stream_name = "Dummy-Playback", - .channels_min = 1, - .channels_max = 16, - .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S32_LE, - }, - .capture = { - .stream_name = "Dummy-Capture", - .channels_min = 1, - .channels_max = 16, - .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S32_LE, - }, - }, + .name = "I2S-DAP", + .playback = { + .stream_name = "DAP-Playback", + .channels_min = 1, + .channels_max = 16, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .capture = { + .stream_name = "DAP-Capture", + .channels_min = 1, + .channels_max = 16, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &tegra210_i2s_dai_ops, + .symmetric_rates = 1, + }, }; static const char * const tegra210_i2s_stereo_conv_text[] = { @@ -738,20 +608,6 @@ static const struct snd_kcontrol_new tegra210_i2s_controls[] = { tegra210_i2s_put_control), SOC_SINGLE_EXT("FSYNC Width", 0, 0, 255, 0, tegra210_i2s_get_control, tegra210_i2s_put_control), - SOC_SINGLE_EXT("Sample Rate", 0, 0, 192000, 0, tegra210_i2s_get_control, - tegra210_i2s_put_control), - SOC_ENUM_EXT("Playback Audio Bit Format", tegra210_i2s_format_enum, - tegra210_i2s_get_control, tegra210_i2s_put_control), - SOC_ENUM_EXT("Capture Audio Bit Format", tegra210_i2s_format_enum, - tegra210_i2s_get_control, tegra210_i2s_put_control), - SOC_ENUM_EXT("Client Bit Format", tegra210_i2s_format_enum, - tegra210_i2s_get_control, tegra210_i2s_put_control), - SOC_SINGLE_EXT("Playback Audio Channels", 0, 0, 16, 0, - tegra210_i2s_get_control, tegra210_i2s_put_control), - SOC_SINGLE_EXT("Capture Audio Channels", 0, 0, 16, 0, - tegra210_i2s_get_control, tegra210_i2s_put_control), - SOC_SINGLE_EXT("Client Channels", 0, 0, 16, 0, - tegra210_i2s_get_control, tegra210_i2s_put_control), SOC_ENUM_EXT("Capture Stereo To Mono", tegra210_i2s_stereo_conv_enum, tegra210_i2s_get_control, tegra210_i2s_put_control), SOC_ENUM_EXT("Capture Mono To Stereo", tegra210_i2s_mono_conv_enum, @@ -773,32 +629,21 @@ static const struct snd_soc_dapm_widget tegra210_i2s_widgets[] = { 0, 0, tegra210_i2s_init, SND_SOC_DAPM_PRE_PMU), SND_SOC_DAPM_MIC("MIC", NULL), SND_SOC_DAPM_SPK("SPK", NULL), - }; static const struct snd_soc_dapm_route tegra210_i2s_routes[] = { -#if IS_ENABLED(CONFIG_TEGRA_DPCM) /* Playback route from XBAR */ { "XBAR-Playback", NULL, "XBAR-TX" }, { "CIF-Playback", NULL, "XBAR-Playback" }, - /* Capture route to XBAR */ - { "XBAR-RX", NULL, "XBAR-Capture" }, - { "XBAR-Capture", NULL, "CIF-Capture" }, - { "RX", NULL, "CIF-Playback" }, { "DAP-Playback", NULL, "RX" }, { "SPK", NULL, "DAP-Playback" }, + /* Capture route to XBAR */ + { "XBAR-RX", NULL, "XBAR-Capture" }, + { "XBAR-Capture", NULL, "CIF-Capture" }, { "CIF-Capture", NULL, "TX" }, { "TX", NULL, "DAP-Capture" }, { "DAP-Capture", NULL, "MIC" }, -#else - { "RX", NULL, "CIF-Playback" }, - { "DAP-Capture", NULL, "RX" }, - { "CIF-Capture", NULL, "TX" }, - { "TX", NULL, "DAP-Playback" }, - { "Dummy-Capture", NULL, "MIC" }, - { "SPK", NULL, "Dummy-Playback" }, -#endif }; static const struct snd_soc_component_driver tegra210_i2s_cmpnt = {