ASoC: tegra: Fix mbdrc driver issues

- MBDRC status register should be defined as volatile.

- MBDRC master volume control was not working for
  expected volume range. Updated the control so that it can
  work for -256dB to 255dB gain. Control can take values
  from 0 to 512 that is mapped to -256 to 256dB. The dB
  info is added as metadata of control.

  kcontrol defination will look like below:
    amixer -c 1 cget name='OPE1 mbdrc master volume'
    numid=1187,iface=MIXER,name='OPE1 mbdrc master volume'
    ; type=INTEGER,access=rw---R--,values=1,min=0,max=512,step=0
    : values=256
    | dBminmax-min=-256.00dB,max=255.00dB

Bug 200753407

Signed-off-by: Sheetal <sheetal@nvidia.com>
Change-Id: I707a89074342083b71f906f15ead243ee317a43b
Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.10/+/2601115
Reviewed-by: svcacv <svcacv@nvidia.com>
Reviewed-by: Sameer Pujar <spujar@nvidia.com>
Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com>
Reviewed-by: Sharad Gupta <sharadg@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
Sheetal
2021-10-12 11:09:20 +05:30
committed by Sameer Pujar
parent 719434d072
commit 99eec7ce60
2 changed files with 49 additions and 5 deletions

View File

@@ -11,6 +11,7 @@
#include <linux/regmap.h>
#include <sound/core.h>
#include <sound/soc.h>
#include <sound/tlv.h>
#include "tegra210_ahub.h"
#include "tegra210_mbdrc.h"
@@ -344,6 +345,43 @@ static int tegra210_mbdrc_param_info(struct snd_kcontrol *kcontrol,
return 0;
}
static int tegra210_mbdrc_vol_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
unsigned long long fls_val = 1ULL << fls(mc->max);
unsigned int mask = fls_val - 1;
int val;
regmap_read(ope->mbdrc_regmap, mc->reg, &val);
ucontrol->value.integer.value[0] = ((val >> mc->shift) -
TEGRA210_MBDRC_MASTER_VOL_MIN) & mask;
return 0;
}
static int tegra210_mbdrc_vol_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
unsigned long long fls_val = 1ULL << fls(mc->max);
unsigned int mask = fls_val - 1;
unsigned int val;
val = (ucontrol->value.integer.value[0] & mask);
val = val + TEGRA210_MBDRC_MASTER_VOL_MIN;
val = val << mc->shift;
return regmap_write(ope->mbdrc_regmap, mc->reg, val);
}
static const char * const tegra210_mbdrc_mode_text[] = {
"bypass", "fullband", "dualband", "multiband"
};
@@ -389,6 +427,8 @@ static const struct soc_enum tegra210_mbdrc_frame_size_enum =
TEGRA_MBDRC_BYTES_EXT(xname, xbase, TEGRA210_MBDRC_FILTER_COUNT, \
xshift, xmask, xinfo)
static const DECLARE_TLV_DB_MINMAX(mdbrc_vol_tlv, -25600, 25500);
static const struct snd_kcontrol_new tegra210_mbdrc_controls[] = {
SOC_ENUM_EXT("mbdrc peak-rms mode", tegra210_mbdrc_peak_rms_enum,
tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
@@ -406,9 +446,6 @@ static const struct snd_kcontrol_new tegra210_mbdrc_controls[] = {
SOC_SINGLE_EXT("mbdrc shift control", TEGRA210_MBDRC_CONFIG,
TEGRA210_MBDRC_CONFIG_SHIFT_CTRL_SHIFT, 0x1f, 0,
tegra210_mbdrc_get, tegra210_mbdrc_put),
SOC_SINGLE_EXT("mbdrc master volume", TEGRA210_MBDRC_MASTER_VOLUME,
TEGRA210_MBDRC_MASTER_VOLUME_SHIFT, 0xffffffff, 0,
tegra210_mbdrc_get, tegra210_mbdrc_put),
SOC_SINGLE_EXT("mbdrc fast attack factor", TEGRA210_MBDRC_FAST_FACTOR,
TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT, 0xffff, 0,
tegra210_mbdrc_get, tegra210_mbdrc_put),
@@ -416,6 +453,11 @@ static const struct snd_kcontrol_new tegra210_mbdrc_controls[] = {
TEGRA210_MBDRC_FAST_FACTOR_RELEASE_SHIFT, 0xffff, 0,
tegra210_mbdrc_get, tegra210_mbdrc_put),
SOC_SINGLE_RANGE_EXT_TLV("mbdrc master volume", TEGRA210_MBDRC_MASTER_VOLUME,
TEGRA210_MBDRC_MASTER_VOLUME_SHIFT, TEGRA210_MBDRC_MASTER_VOL_MIN,
TEGRA210_MBDRC_MASTER_VOL_MAX, 0,
tegra210_mbdrc_vol_get, tegra210_mbdrc_vol_put, mdbrc_vol_tlv),
TEGRA_SOC_BYTES_EXT("mbdrc iir stages", TEGRA210_MBDRC_IIR_CONFIG,
TEGRA210_MBDRC_FILTER_COUNT,
TEGRA210_MBDRC_IIR_CONFIG_NUM_STAGES_SHIFT,
@@ -602,6 +644,7 @@ static bool tegra210_mbdrc_volatile_reg(struct device *dev, unsigned int reg)
switch (reg) {
case TEGRA210_MBDRC_SOFT_RESET:
case TEGRA210_MBDRC_STATUS:
case TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL:
case TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_DATA:
return true;

View File

@@ -89,8 +89,9 @@ enum {
#define TEGRA210_MBDRC_CHANNEL_MASK_MASK (0xff << TEGRA210_MBDRC_CHANNEL_MASK_SHIFT)
/* Fields for TEGRA210_MBDRC_MASTER_VOLUME */
#define TEGRA210_MBDRC_MASTER_VOLUME_SHIFT 0
#define TEGRA210_MBDRC_MASTER_VOLUME_MASK (0xffffffff << TEGRA210_MBDRC_MASTER_VOLUME_SHIFT)
#define TEGRA210_MBDRC_MASTER_VOLUME_SHIFT 23
#define TEGRA210_MBDRC_MASTER_VOL_MIN -256
#define TEGRA210_MBDRC_MASTER_VOL_MAX 256
/* Fields for TEGRA210_MBDRC_FAST_FACTOR */
#define TEGRA210_MBDRC_FAST_FACTOR_RELEASE_SHIFT 16