Commit b31f8feb authored by Sameer Pujar's avatar Sameer Pujar Committed by Mark Brown

ASoC: tegra: Fix kcontrol put callback in SFC

The kcontrol put callback is expected to return 1 when there is change
in HW or when the update is acknowledged by driver. This would ensure
that change notifications are sent to subscribed applications. Filter
out duplicate updates in SFC driver.

Fixes: b2f74ec5 ("ASoC: tegra: Add Tegra210 based SFC driver")
Signed-off-by: default avatarSameer Pujar <spujar@nvidia.com>
Suggested-by: default avatarJaroslav Kysela <perex@perex.cz>
Suggested-by: default avatarMark Brown <broonie@kernel.org>
Reviewed-by: default avatarTakashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/1637219231-406-14-git-send-email-spujar@nvidia.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent c7b34b51
...@@ -3244,49 +3244,107 @@ static int tegra210_sfc_init(struct snd_soc_dapm_widget *w, ...@@ -3244,49 +3244,107 @@ static int tegra210_sfc_init(struct snd_soc_dapm_widget *w,
return tegra210_sfc_write_coeff_ram(cmpnt); return tegra210_sfc_write_coeff_ram(cmpnt);
} }
static int tegra210_sfc_get_control(struct snd_kcontrol *kcontrol, static int tegra210_sfc_iget_stereo_to_mono(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt);
if (strstr(kcontrol->id.name, "Input Stereo To Mono")) ucontrol->value.enumerated.item[0] = sfc->stereo_to_mono[SFC_RX_PATH];
ucontrol->value.enumerated.item[0] =
sfc->stereo_to_mono[SFC_RX_PATH];
else if (strstr(kcontrol->id.name, "Input Mono To Stereo"))
ucontrol->value.enumerated.item[0] =
sfc->mono_to_stereo[SFC_RX_PATH];
else if (strstr(kcontrol->id.name, "Output Stereo To Mono"))
ucontrol->value.enumerated.item[0] =
sfc->stereo_to_mono[SFC_TX_PATH];
else if (strstr(kcontrol->id.name, "Output Mono To Stereo"))
ucontrol->value.enumerated.item[0] =
sfc->mono_to_stereo[SFC_TX_PATH];
return 0; return 0;
} }
static int tegra210_sfc_put_control(struct snd_kcontrol *kcontrol, static int tegra210_sfc_iput_stereo_to_mono(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt);
unsigned int value = ucontrol->value.enumerated.item[0];
if (strstr(kcontrol->id.name, "Input Stereo To Mono")) if (value == sfc->stereo_to_mono[SFC_RX_PATH])
sfc->stereo_to_mono[SFC_RX_PATH] = return 0;
ucontrol->value.enumerated.item[0];
else if (strstr(kcontrol->id.name, "Input Mono To Stereo")) sfc->stereo_to_mono[SFC_RX_PATH] = value;
sfc->mono_to_stereo[SFC_RX_PATH] =
ucontrol->value.enumerated.item[0]; return 1;
else if (strstr(kcontrol->id.name, "Output Stereo To Mono")) }
sfc->stereo_to_mono[SFC_TX_PATH] =
ucontrol->value.enumerated.item[0]; static int tegra210_sfc_iget_mono_to_stereo(struct snd_kcontrol *kcontrol,
else if (strstr(kcontrol->id.name, "Output Mono To Stereo")) struct snd_ctl_elem_value *ucontrol)
sfc->mono_to_stereo[SFC_TX_PATH] = {
ucontrol->value.enumerated.item[0]; struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
else struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt);
ucontrol->value.enumerated.item[0] = sfc->mono_to_stereo[SFC_RX_PATH];
return 0;
}
static int tegra210_sfc_iput_mono_to_stereo(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);
unsigned int value = ucontrol->value.enumerated.item[0];
if (value == sfc->mono_to_stereo[SFC_RX_PATH])
return 0;
sfc->mono_to_stereo[SFC_RX_PATH] = value;
return 1;
}
static int tegra210_sfc_oget_stereo_to_mono(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.enumerated.item[0] = sfc->stereo_to_mono[SFC_TX_PATH];
return 0;
}
static int tegra210_sfc_oput_stereo_to_mono(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);
unsigned int value = ucontrol->value.enumerated.item[0];
if (value == sfc->stereo_to_mono[SFC_TX_PATH])
return 0; return 0;
sfc->stereo_to_mono[SFC_TX_PATH] = value;
return 1;
}
static int tegra210_sfc_oget_mono_to_stereo(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.enumerated.item[0] = sfc->mono_to_stereo[SFC_TX_PATH];
return 0;
}
static int tegra210_sfc_oput_mono_to_stereo(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);
unsigned int value = ucontrol->value.enumerated.item[0];
if (value == sfc->mono_to_stereo[SFC_TX_PATH])
return 0;
sfc->mono_to_stereo[SFC_TX_PATH] = value;
return 1; return 1;
} }
...@@ -3387,13 +3445,17 @@ static const struct soc_enum tegra210_sfc_mono_conv_enum = ...@@ -3387,13 +3445,17 @@ static const struct soc_enum tegra210_sfc_mono_conv_enum =
static const struct snd_kcontrol_new tegra210_sfc_controls[] = { static const struct snd_kcontrol_new tegra210_sfc_controls[] = {
SOC_ENUM_EXT("Input Stereo To Mono", tegra210_sfc_stereo_conv_enum, SOC_ENUM_EXT("Input Stereo To Mono", tegra210_sfc_stereo_conv_enum,
tegra210_sfc_get_control, tegra210_sfc_put_control), tegra210_sfc_iget_stereo_to_mono,
tegra210_sfc_iput_stereo_to_mono),
SOC_ENUM_EXT("Input Mono To Stereo", tegra210_sfc_mono_conv_enum, SOC_ENUM_EXT("Input Mono To Stereo", tegra210_sfc_mono_conv_enum,
tegra210_sfc_get_control, tegra210_sfc_put_control), tegra210_sfc_iget_mono_to_stereo,
tegra210_sfc_iput_mono_to_stereo),
SOC_ENUM_EXT("Output Stereo To Mono", tegra210_sfc_stereo_conv_enum, SOC_ENUM_EXT("Output Stereo To Mono", tegra210_sfc_stereo_conv_enum,
tegra210_sfc_get_control, tegra210_sfc_put_control), tegra210_sfc_oget_stereo_to_mono,
tegra210_sfc_oput_stereo_to_mono),
SOC_ENUM_EXT("Output Mono To Stereo", tegra210_sfc_mono_conv_enum, SOC_ENUM_EXT("Output Mono To Stereo", tegra210_sfc_mono_conv_enum,
tegra210_sfc_get_control, tegra210_sfc_put_control), tegra210_sfc_oget_mono_to_stereo,
tegra210_sfc_oput_mono_to_stereo),
}; };
static const struct snd_soc_component_driver tegra210_sfc_cmpnt = { static const struct snd_soc_component_driver tegra210_sfc_cmpnt = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment