mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
tegra-alt: mvc: Updated mixer controls
Following updates: - "input bit format" ctl to set RX CIF bit-width - 100x scaling to "Vol" ctl for more granularity - Fixes in mixer ctl "get" functions so that current value is read - Fix in "Curve Type" ctl so that default volume gets set Bug 1936284 Change-Id: Ib54b17266c7c3a3e9e42cab13195389c5fa1fbe7 Signed-off-by: Viswanath L <viswanathl@nvidia.com> Reviewed-on: http://git-master/r/1497628 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Ravindra Lokhande <rlokhande@nvidia.com>
This commit is contained in:
committed by
Sameer Pujar
parent
725219888e
commit
7a1abcd3f1
@@ -141,26 +141,25 @@ static int tegra210_mvc_get_vol(struct snd_kcontrol *kcontrol,
|
|||||||
struct tegra210_mvc *mvc = snd_soc_codec_get_drvdata(codec);
|
struct tegra210_mvc *mvc = snd_soc_codec_get_drvdata(codec);
|
||||||
unsigned int reg = mc->reg;
|
unsigned int reg = mc->reg;
|
||||||
|
|
||||||
pm_runtime_get_sync(codec->dev);
|
|
||||||
if (reg == TEGRA210_MVC_TARGET_VOL) {
|
if (reg == TEGRA210_MVC_TARGET_VOL) {
|
||||||
s32 val;
|
s32 val = mvc->volume;
|
||||||
|
|
||||||
regmap_read(mvc->regmap, reg, &val);
|
|
||||||
if (mvc->curve_type == CURVE_POLY)
|
if (mvc->curve_type == CURVE_POLY)
|
||||||
val >>= 24;
|
val = ((val >> 16) * 100) >> 8;
|
||||||
else {
|
else {
|
||||||
val >>= 8;
|
val = (val * 100) >> 8;
|
||||||
val += 120;
|
val += 12000;
|
||||||
}
|
}
|
||||||
ucontrol->value.integer.value[0] = val;
|
ucontrol->value.integer.value[0] = val;
|
||||||
} else {
|
} else {
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
|
pm_runtime_get_sync(codec->dev);
|
||||||
regmap_read(mvc->regmap, reg, &val);
|
regmap_read(mvc->regmap, reg, &val);
|
||||||
|
pm_runtime_put(codec->dev);
|
||||||
ucontrol->value.integer.value[0] =
|
ucontrol->value.integer.value[0] =
|
||||||
((val & TEGRA210_MVC_MUTE_MASK) != 0);
|
((val & TEGRA210_MVC_MUTE_MASK) != 0);
|
||||||
}
|
}
|
||||||
pm_runtime_put(codec->dev);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,15 +188,18 @@ static int tegra210_mvc_put_vol(struct snd_kcontrol *kcontrol,
|
|||||||
} while (value & TEGRA210_MVC_VOLUME_SWITCH_MASK);
|
} while (value & TEGRA210_MVC_VOLUME_SWITCH_MASK);
|
||||||
|
|
||||||
if (reg == TEGRA210_MVC_TARGET_VOL) {
|
if (reg == TEGRA210_MVC_TARGET_VOL) {
|
||||||
|
/* Volume control read from mixer ctl is with */
|
||||||
|
/* 100x scaling; for CURVE_POLY the reg range */
|
||||||
|
/* is 0-100 (linear, Q24) and for CURVE_LINEAR */
|
||||||
|
/* it is -120dB to +40dB (Q8) */
|
||||||
if (mvc->curve_type == CURVE_POLY) {
|
if (mvc->curve_type == CURVE_POLY) {
|
||||||
val = ucontrol->value.integer.value[0];
|
val = ucontrol->value.integer.value[0];
|
||||||
if (val > 100)
|
if (val > 10000)
|
||||||
val = 100;
|
val = 10000;
|
||||||
mvc->volume = val * (1<<24);
|
mvc->volume = ((val * (1<<8)) / 100) << 16;
|
||||||
} else {
|
} else {
|
||||||
val = ucontrol->value.integer.value[0] - 120;
|
val = ucontrol->value.integer.value[0] - 12000;
|
||||||
val <<= 8;
|
mvc->volume = (val * (1<<8)) / 100;
|
||||||
mvc->volume = val;
|
|
||||||
}
|
}
|
||||||
ret = regmap_write(mvc->regmap, reg, mvc->volume);
|
ret = regmap_write(mvc->regmap, reg, mvc->volume);
|
||||||
} else {
|
} else {
|
||||||
@@ -221,15 +223,8 @@ static int tegra210_mvc_get_curve_type(struct snd_kcontrol *kcontrol,
|
|||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
||||||
struct tegra210_mvc *mvc = snd_soc_codec_get_drvdata(codec);
|
struct tegra210_mvc *mvc = snd_soc_codec_get_drvdata(codec);
|
||||||
unsigned int reg = TEGRA210_MVC_CTRL;
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
pm_runtime_get_sync(codec->dev);
|
ucontrol->value.integer.value[0] = mvc->curve_type;
|
||||||
regmap_read(mvc->regmap, reg, &val);
|
|
||||||
ucontrol->value.integer.value[0] =
|
|
||||||
(val & TEGRA210_MVC_CURVE_TYPE_MASK) >>
|
|
||||||
TEGRA210_MVC_CURVE_TYPE_SHIFT;
|
|
||||||
pm_runtime_put(codec->dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -276,6 +271,11 @@ static int tegra210_mvc_put_curve_type(struct snd_kcontrol *kcontrol,
|
|||||||
else
|
else
|
||||||
mvc->volume = TEGRA210_MVC_INIT_VOL_DEFAULT_LINEAR;
|
mvc->volume = TEGRA210_MVC_INIT_VOL_DEFAULT_LINEAR;
|
||||||
|
|
||||||
|
regmap_write(mvc->regmap, TEGRA210_MVC_TARGET_VOL, mvc->volume);
|
||||||
|
ret |= regmap_update_bits(mvc->regmap, TEGRA210_MVC_SWITCH,
|
||||||
|
TEGRA210_MVC_VOLUME_SWITCH_MASK,
|
||||||
|
TEGRA210_MVC_VOLUME_SWITCH_TRIGGER);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
pm_runtime_put(codec->dev);
|
pm_runtime_put(codec->dev);
|
||||||
|
|
||||||
@@ -288,7 +288,10 @@ static int tegra210_mvc_get_audio_bits(struct snd_kcontrol *kcontrol,
|
|||||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
||||||
struct tegra210_mvc *mvc = snd_soc_codec_get_drvdata(codec);
|
struct tegra210_mvc *mvc = snd_soc_codec_get_drvdata(codec);
|
||||||
|
|
||||||
|
if (mvc->audio_bits > 0)
|
||||||
ucontrol->value.integer.value[0] = (mvc->audio_bits + 1) * 4;
|
ucontrol->value.integer.value[0] = (mvc->audio_bits + 1) * 4;
|
||||||
|
else
|
||||||
|
ucontrol->value.integer.value[0] = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -308,34 +311,43 @@ static int tegra210_mvc_put_audio_bits(struct snd_kcontrol *kcontrol,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
static int tegra210_mvc_get_format(struct snd_kcontrol *kcontrol,
|
||||||
static int tegra210_mvc_get_channels(struct snd_kcontrol *kcontrol,
|
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
||||||
struct tegra210_mvc *mvc = snd_soc_codec_get_drvdata(codec);
|
struct tegra210_mvc *mvc = snd_soc_codec_get_drvdata(codec);
|
||||||
|
|
||||||
|
/* get the format control flag */
|
||||||
|
if (strstr(kcontrol->id.name, "input bit format"))
|
||||||
|
ucontrol->value.integer.value[0] = mvc->format_in;
|
||||||
|
else if (strstr(kcontrol->id.name, "Channels"))
|
||||||
ucontrol->value.integer.value[0] = mvc->cif_channels;
|
ucontrol->value.integer.value[0] = mvc->cif_channels;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tegra210_mvc_put_channels(struct snd_kcontrol *kcontrol,
|
static int tegra210_mvc_put_format(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
||||||
struct tegra210_mvc *mvc = snd_soc_codec_get_drvdata(codec);
|
struct tegra210_mvc *mvc = snd_soc_codec_get_drvdata(codec);
|
||||||
unsigned int val;
|
unsigned int value = ucontrol->value.integer.value[0];
|
||||||
|
|
||||||
val = ucontrol->value.integer.value[0];
|
/* set the format control flag */
|
||||||
if ((val > 0) && (val <= 8))
|
if (strstr(kcontrol->id.name, "input bit format"))
|
||||||
mvc->cif_channels = val;
|
mvc->format_in = value;
|
||||||
else
|
else if (strstr(kcontrol->id.name, "Channels"))
|
||||||
return -EINVAL;
|
mvc->cif_channels = value;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const int tegra210_mvc_fmt_values[] = {
|
||||||
|
0,
|
||||||
|
TEGRA210_AUDIOCIF_BITS_16,
|
||||||
|
TEGRA210_AUDIOCIF_BITS_32,
|
||||||
|
};
|
||||||
|
|
||||||
static int tegra210_mvc_set_audio_cif(struct tegra210_mvc *mvc,
|
static int tegra210_mvc_set_audio_cif(struct tegra210_mvc *mvc,
|
||||||
struct snd_pcm_hw_params *params,
|
struct snd_pcm_hw_params *params,
|
||||||
unsigned int reg)
|
unsigned int reg)
|
||||||
@@ -371,6 +383,10 @@ static int tegra210_mvc_set_audio_cif(struct tegra210_mvc *mvc,
|
|||||||
cif_conf.audio_bits = audio_bits;
|
cif_conf.audio_bits = audio_bits;
|
||||||
cif_conf.client_bits = audio_bits;
|
cif_conf.client_bits = audio_bits;
|
||||||
|
|
||||||
|
/* Override input format to MVC, if set */
|
||||||
|
if (mvc->format_in && (reg == TEGRA210_MVC_AXBAR_RX_CIF_CTRL))
|
||||||
|
cif_conf.audio_bits = tegra210_mvc_fmt_values[mvc->format_in];
|
||||||
|
|
||||||
mvc->soc_data->set_audio_cif(mvc->regmap, reg, &cif_conf);
|
mvc->soc_data->set_audio_cif(mvc->regmap, reg, &cif_conf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -458,8 +474,19 @@ static const char * const tegra210_mvc_curve_type_text[] = {
|
|||||||
static const struct soc_enum tegra210_mvc_curve_type_ctrl =
|
static const struct soc_enum tegra210_mvc_curve_type_ctrl =
|
||||||
SOC_ENUM_SINGLE_EXT(2, tegra210_mvc_curve_type_text);
|
SOC_ENUM_SINGLE_EXT(2, tegra210_mvc_curve_type_text);
|
||||||
|
|
||||||
|
static const char * const tegra210_mvc_format_text[] = {
|
||||||
|
"None",
|
||||||
|
"16",
|
||||||
|
"32",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct soc_enum tegra210_mvc_format_enum =
|
||||||
|
SOC_ENUM_SINGLE(SND_SOC_NOPM, 0,
|
||||||
|
ARRAY_SIZE(tegra210_mvc_format_text),
|
||||||
|
tegra210_mvc_format_text);
|
||||||
|
|
||||||
static const struct snd_kcontrol_new tegra210_mvc_vol_ctrl[] = {
|
static const struct snd_kcontrol_new tegra210_mvc_vol_ctrl[] = {
|
||||||
SOC_SINGLE_EXT("Vol", TEGRA210_MVC_TARGET_VOL, 0, 160, 0,
|
SOC_SINGLE_EXT("Vol", TEGRA210_MVC_TARGET_VOL, 0, 16000, 0,
|
||||||
tegra210_mvc_get_vol, tegra210_mvc_put_vol),
|
tegra210_mvc_get_vol, tegra210_mvc_put_vol),
|
||||||
SOC_SINGLE_EXT("Mute", TEGRA210_MVC_CTRL, 0, 1, 0,
|
SOC_SINGLE_EXT("Mute", TEGRA210_MVC_CTRL, 0, 1, 0,
|
||||||
tegra210_mvc_get_vol, tegra210_mvc_put_vol),
|
tegra210_mvc_get_vol, tegra210_mvc_put_vol),
|
||||||
@@ -467,8 +494,10 @@ static const struct snd_kcontrol_new tegra210_mvc_vol_ctrl[] = {
|
|||||||
tegra210_mvc_get_curve_type, tegra210_mvc_put_curve_type),
|
tegra210_mvc_get_curve_type, tegra210_mvc_put_curve_type),
|
||||||
SOC_SINGLE_EXT("Bits", 0, 0, 32, 0,
|
SOC_SINGLE_EXT("Bits", 0, 0, 32, 0,
|
||||||
tegra210_mvc_get_audio_bits, tegra210_mvc_put_audio_bits),
|
tegra210_mvc_get_audio_bits, tegra210_mvc_put_audio_bits),
|
||||||
SOC_SINGLE_EXT("Channels", 0, 0, 16, 0,
|
SOC_SINGLE_EXT("Channels", 0, 0, 8, 0,
|
||||||
tegra210_mvc_get_channels, tegra210_mvc_put_channels),
|
tegra210_mvc_get_format, tegra210_mvc_put_format),
|
||||||
|
SOC_ENUM_EXT("input bit format", tegra210_mvc_format_enum,
|
||||||
|
tegra210_mvc_get_format, tegra210_mvc_put_format),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct snd_soc_dai_driver tegra210_mvc_dais[] = {
|
static struct snd_soc_dai_driver tegra210_mvc_dais[] = {
|
||||||
@@ -658,7 +687,7 @@ static int tegra210_mvc_platform_probe(struct platform_device *pdev)
|
|||||||
mvc->poly_coeff[7] = 5527252;
|
mvc->poly_coeff[7] = 5527252;
|
||||||
mvc->poly_coeff[8] = -785042;
|
mvc->poly_coeff[8] = -785042;
|
||||||
mvc->curve_type = CURVE_LINEAR;
|
mvc->curve_type = CURVE_LINEAR;
|
||||||
mvc->volume = TEGRA210_MVC_INIT_VOL_DEFAULT_POLY;
|
mvc->volume = TEGRA210_MVC_INIT_VOL_DEFAULT_LINEAR;
|
||||||
|
|
||||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
if (!mem) {
|
if (!mem) {
|
||||||
|
|||||||
Reference in New Issue
Block a user