ASoC: tegra: remove channel hard coding in SFC

Hardcoding of CIF channels based on stereo/mono conversion settings is
removed and individual controls are provided for setting audio/client
channels. This is in line with the approach adopted for upstream.

Bug 200528522
Bug 2845498

Change-Id: If26b365d6f79f961ef3deeadbd61dbf0dd42f35e
Signed-off-by: Viswanath L <viswanathl@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2263865
(manually cherry picked from commit 404f9fa1f37f5389fa8de685e6581db23b7dba10)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.9/+/2361551
GVS: Gerrit_Virtual_Submit
Reviewed-by: Sameer Pujar <spujar@nvidia.com>
Reviewed-by: Sharad Gupta <sharadg@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: Sameer Pujar <spujar@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Viswanath L
2020-06-16 14:18:21 +05:30
committed by Sameer Pujar
parent 24a60cd984
commit f79c4d54ef
2 changed files with 73 additions and 73 deletions

View File

@@ -2957,7 +2957,7 @@ static int tegra210_sfc_set_audio_cif(struct tegra210_sfc *sfc,
struct snd_pcm_hw_params *params, struct snd_pcm_hw_params *params,
unsigned int reg) unsigned int reg)
{ {
int channels, audio_bits; int channels, audio_bits, path;
struct tegra_cif_conf cif_conf; struct tegra_cif_conf cif_conf;
memset(&cif_conf, 0, sizeof(struct tegra_cif_conf)); memset(&cif_conf, 0, sizeof(struct tegra_cif_conf));
@@ -2975,22 +2975,21 @@ static int tegra210_sfc_set_audio_cif(struct tegra210_sfc *sfc,
return -EINVAL; return -EINVAL;
} }
if (sfc->channels_via_control) path = (reg == TEGRA210_SFC_AXBAR_RX_CIF_CTRL) ?
channels = sfc->channels_via_control; SFC_RX_PATH : SFC_TX_PATH;
if (sfc->stereo_conv_input > 0 && 2 == channels &&
(reg == TEGRA210_SFC_AXBAR_RX_CIF_CTRL)) {
cif_conf.stereo_conv = sfc->stereo_conv_input - 1;
cif_conf.client_ch = 1;
} else if (sfc->mono_conv_output > 0 && 2 == channels &&
(reg == TEGRA210_SFC_AXBAR_TX_CIF_CTRL)) {
cif_conf.mono_conv = sfc->mono_conv_output - 1;
cif_conf.client_ch = 1;
} else {
cif_conf.client_ch = channels;
}
cif_conf.audio_ch = channels; cif_conf.audio_ch = channels;
cif_conf.client_ch = channels;
if (sfc->audio_ch_override[path])
cif_conf.audio_ch = sfc->audio_ch_override[path];
if (sfc->client_ch_override)
cif_conf.client_ch = sfc->client_ch_override;
cif_conf.stereo_conv = sfc->stereo_to_mono[path];
cif_conf.mono_conv = sfc->mono_to_stereo[path];
cif_conf.audio_bits = audio_bits; cif_conf.audio_bits = audio_bits;
if (sfc->format_in && (reg == TEGRA210_SFC_AXBAR_RX_CIF_CTRL)) if (sfc->format_in && (reg == TEGRA210_SFC_AXBAR_RX_CIF_CTRL))
cif_conf.audio_bits = tegra210_sfc_fmt_values[sfc->format_in]; cif_conf.audio_bits = tegra210_sfc_fmt_values[sfc->format_in];
@@ -3133,8 +3132,26 @@ static int tegra210_sfc_get_format(struct snd_kcontrol *kcontrol,
ucontrol->value.integer.value[0] = sfc->format_in; ucontrol->value.integer.value[0] = sfc->format_in;
else if (strstr(kcontrol->id.name, "output")) else if (strstr(kcontrol->id.name, "output"))
ucontrol->value.integer.value[0] = sfc->format_out; ucontrol->value.integer.value[0] = sfc->format_out;
else if (strstr(kcontrol->id.name, "Channels")) else if (strstr(kcontrol->id.name, "Input Audio Channels"))
ucontrol->value.integer.value[0] = sfc->channels_via_control; ucontrol->value.integer.value[0] =
sfc->audio_ch_override[SFC_RX_PATH];
else if (strstr(kcontrol->id.name, "Output Audio Channels"))
ucontrol->value.integer.value[0] =
sfc->audio_ch_override[SFC_TX_PATH];
else if (strstr(kcontrol->id.name, "Client Channels"))
ucontrol->value.integer.value[0] = sfc->client_ch_override;
else if (strstr(kcontrol->id.name, "Input Stereo To Mono"))
ucontrol->value.integer.value[0] =
sfc->stereo_to_mono[SFC_RX_PATH];
else if (strstr(kcontrol->id.name, "Input Mono To Stereo"))
ucontrol->value.integer.value[0] =
sfc->mono_to_stereo[SFC_RX_PATH];
else if (strstr(kcontrol->id.name, "Output Stereo To Mono"))
ucontrol->value.integer.value[0] =
sfc->stereo_to_mono[SFC_TX_PATH];
else if (strstr(kcontrol->id.name, "Output Mono To Stereo"))
ucontrol->value.integer.value[0] =
sfc->mono_to_stereo[SFC_TX_PATH];
return 0; return 0;
} }
@@ -3151,12 +3168,20 @@ static int tegra210_sfc_put_format(struct snd_kcontrol *kcontrol,
sfc->format_in = value; sfc->format_in = value;
else if (strstr(kcontrol->id.name, "output")) else if (strstr(kcontrol->id.name, "output"))
sfc->format_out = value; sfc->format_out = value;
else if (strstr(kcontrol->id.name, "Channels")) { else if (strstr(kcontrol->id.name, "Input Audio Channels"))
if (value >= 0 && value <= 2) sfc->audio_ch_override[SFC_RX_PATH] = value;
sfc->channels_via_control = value; else if (strstr(kcontrol->id.name, "Output Audio Channels"))
else sfc->audio_ch_override[SFC_TX_PATH] = value;
return -EINVAL; else if (strstr(kcontrol->id.name, "Client Channels"))
} sfc->client_ch_override = value;
else if (strstr(kcontrol->id.name, "Input Stereo To Mono"))
sfc->stereo_to_mono[SFC_RX_PATH] = value;
else if (strstr(kcontrol->id.name, "Input Mono To Stereo"))
sfc->mono_to_stereo[SFC_RX_PATH] = value;
else if (strstr(kcontrol->id.name, "Output Stereo To Mono"))
sfc->stereo_to_mono[SFC_TX_PATH] = value;
else if (strstr(kcontrol->id.name, "Output Mono To Stereo"))
sfc->mono_to_stereo[SFC_TX_PATH] = value;
return 0; return 0;
} }
@@ -3251,46 +3276,6 @@ exit:
return ret; return ret;
} }
static int tegra210_sfc_get_stereo_conv(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt);
ucontrol->value.integer.value[0] = sfc->stereo_conv_input;
return 0;
}
static int tegra210_sfc_put_stereo_conv(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt);
sfc->stereo_conv_input = ucontrol->value.integer.value[0];
return 0;
}
static int tegra210_sfc_get_mono_conv(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt);
ucontrol->value.integer.value[0] = sfc->mono_conv_output;
return 0;
}
static int tegra210_sfc_put_mono_conv(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt);
sfc->mono_conv_output = ucontrol->value.integer.value[0];
return 0;
}
static struct snd_soc_dai_ops tegra210_sfc_in_dai_ops = { static struct snd_soc_dai_ops tegra210_sfc_in_dai_ops = {
.hw_params = tegra210_sfc_in_hw_params, .hw_params = tegra210_sfc_in_hw_params,
}; };
@@ -3350,11 +3335,11 @@ static const char * const tegra210_sfc_format_text[] = {
}; };
static const char * const tegra210_sfc_stereo_conv_text[] = { static const char * const tegra210_sfc_stereo_conv_text[] = {
"None", "CH0", "CH1", "AVG", "CH0", "CH1", "AVG",
}; };
static const char * const tegra210_sfc_mono_conv_text[] = { static const char * const tegra210_sfc_mono_conv_text[] = {
"None", "ZERO", "COPY", "ZERO", "COPY",
}; };
static const struct soc_enum tegra210_sfc_format_enum = static const struct soc_enum tegra210_sfc_format_enum =
@@ -3381,14 +3366,22 @@ static const struct snd_kcontrol_new tegra210_sfc_controls[] = {
tegra210_sfc_get_format, tegra210_sfc_put_format), tegra210_sfc_get_format, tegra210_sfc_put_format),
SOC_ENUM_EXT("output bit format", tegra210_sfc_format_enum, SOC_ENUM_EXT("output bit format", tegra210_sfc_format_enum,
tegra210_sfc_get_format, tegra210_sfc_put_format), tegra210_sfc_get_format, tegra210_sfc_put_format),
SOC_SINGLE_EXT("Channels", 0, 0, 2, 0, SOC_SINGLE_EXT("Input Audio Channels", 0, 0, 2, 0,
tegra210_sfc_get_format, tegra210_sfc_put_format),
SOC_SINGLE_EXT("Output Audio Channels", 0, 0, 2, 0,
tegra210_sfc_get_format, tegra210_sfc_put_format),
SOC_SINGLE_EXT("Client Channels", 0, 0, 2, 0,
tegra210_sfc_get_format, tegra210_sfc_put_format), tegra210_sfc_get_format, tegra210_sfc_put_format),
SOC_SINGLE_EXT("init", 0, 0, 1, 0, SOC_SINGLE_EXT("init", 0, 0, 1, 0,
tegra210_sfc_init_get, tegra210_sfc_init_put), tegra210_sfc_init_get, tegra210_sfc_init_put),
SOC_ENUM_EXT("input stereo conv", tegra210_sfc_stereo_conv_enum, SOC_ENUM_EXT("Input Stereo To Mono", tegra210_sfc_stereo_conv_enum,
tegra210_sfc_get_stereo_conv, tegra210_sfc_put_stereo_conv), tegra210_sfc_get_format, tegra210_sfc_put_format),
SOC_ENUM_EXT("output mono conv", tegra210_sfc_mono_conv_enum, SOC_ENUM_EXT("Input Mono To Stereo", tegra210_sfc_mono_conv_enum,
tegra210_sfc_get_mono_conv, tegra210_sfc_put_mono_conv), tegra210_sfc_get_format, tegra210_sfc_put_format),
SOC_ENUM_EXT("Output Stereo To Mono", tegra210_sfc_stereo_conv_enum,
tegra210_sfc_get_format, tegra210_sfc_put_format),
SOC_ENUM_EXT("Output Mono To Stereo", tegra210_sfc_mono_conv_enum,
tegra210_sfc_get_format, tegra210_sfc_put_format),
}; };
static struct snd_soc_component_driver tegra210_sfc_cmpnt = { static struct snd_soc_component_driver tegra210_sfc_cmpnt = {

View File

@@ -70,6 +70,12 @@
/* SRC coefficients */ /* SRC coefficients */
#define TEGRA210_SFC_COEF_RAM_DEPTH 64 #define TEGRA210_SFC_COEF_RAM_DEPTH 64
enum tegra210_sfc_path {
SFC_RX_PATH,
SFC_TX_PATH,
SFC_PATHS,
};
struct tegra210_sfc { struct tegra210_sfc {
int srate_in; int srate_in;
int srate_out; int srate_out;
@@ -78,9 +84,10 @@ struct tegra210_sfc {
struct regmap *regmap; struct regmap *regmap;
struct snd_pcm_hw_params in_hw_params; struct snd_pcm_hw_params in_hw_params;
struct snd_pcm_hw_params out_hw_params; struct snd_pcm_hw_params out_hw_params;
int stereo_conv_input; int audio_ch_override[SFC_PATHS];
int mono_conv_output; int client_ch_override; /* common for both TX and RX */
unsigned int channels_via_control; int stereo_to_mono[SFC_PATHS];
int mono_to_stereo[SFC_PATHS];
}; };
#endif #endif