From 7a799c007b72feaa1b65a2d8a1d236e14c7b455b Mon Sep 17 00:00:00 2001 From: Hariharan Sivaraman Date: Fri, 10 Mar 2017 13:18:13 +0530 Subject: [PATCH] sound: tegra-alt: PEQ enhancement Add support for 8 channels in PEQ. Add support to program gain and shift RAMs with integer coefficients instead of byte arrays. Fix OPE enable writes to incorrect regmap Jira EMA-393 Change-Id: Ib509a9f95f4c152c2210f88975a1f7572d79ba08 Reviewed-on: http://git-master/r/1318570 Reviewed-by: svccoveritychecker GVS: Gerrit_Virtual_Submit Tested-by: Hariharan Sivaraman Reviewed-by: Nitin Pai --- sound/soc/tegra-alt/tegra210_mbdrc_alt.c | 76 +++++++++++++++++------- sound/soc/tegra-alt/tegra210_ope_alt.c | 10 +++- sound/soc/tegra-alt/tegra210_peq_alt.c | 59 +++++++++++++++--- 3 files changed, 116 insertions(+), 29 deletions(-) diff --git a/sound/soc/tegra-alt/tegra210_mbdrc_alt.c b/sound/soc/tegra-alt/tegra210_mbdrc_alt.c index 35a2c67a..0b2d7313 100644 --- a/sound/soc/tegra-alt/tegra210_mbdrc_alt.c +++ b/sound/soc/tegra-alt/tegra210_mbdrc_alt.c @@ -1,7 +1,7 @@ /* * tegra210_mbdrc_alt.c - Tegra210 MBDRC driver * - * Copyright (c) 2014 NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -344,6 +344,17 @@ static int tegra210_mbdrc_biquad_coeffs_put(struct snd_kcontrol *kcontrol, return 0; } +static int tegra210_mbdrc_param_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct soc_bytes *params = (void *)kcontrol->private_value; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = params->num_regs; + + return 0; +} + static const char * const tegra210_mbdrc_mode_text[] = { "bypass", "fullband", "dualband", "multiband" }; @@ -380,13 +391,14 @@ static const struct soc_enum tegra210_mbdrc_frame_size_enum = TEGRA210_MBDRC_CONFIG_FRAME_SIZE_SHIFT, 7, tegra210_mbdrc_frame_size_text); -#define TEGRA_MBDRC_BYTES_EXT(xname, xbase, xregs, xshift, xmask) \ +#define TEGRA_MBDRC_BYTES_EXT(xname, xbase, xregs, xshift, xmask, xinfo) \ TEGRA_SOC_BYTES_EXT(xname, xbase, xregs, xshift, xmask, \ - tegra210_mbdrc_band_params_get, tegra210_mbdrc_band_params_put) + tegra210_mbdrc_band_params_get, tegra210_mbdrc_band_params_put, \ + tegra210_mbdrc_param_info) -#define TEGRA_MBDRC_BAND_BYTES_EXT(xname, xbase, xshift, xmask) \ +#define TEGRA_MBDRC_BAND_BYTES_EXT(xname, xbase, xshift, xmask, xinfo) \ TEGRA_MBDRC_BYTES_EXT(xname, xbase, TEGRA210_MBDRC_FILTER_COUNT, \ - xshift, xmask) + xshift, xmask, xinfo) static const struct snd_kcontrol_new tegra210_mbdrc_controls[] = { SOC_ENUM_EXT("mbdrc peak-rms mode", tegra210_mbdrc_peak_rms_enum, @@ -419,79 +431,101 @@ static const struct snd_kcontrol_new tegra210_mbdrc_controls[] = { TEGRA210_MBDRC_FILTER_COUNT, TEGRA210_MBDRC_IIR_CONFIG_NUM_STAGES_SHIFT, TEGRA210_MBDRC_IIR_CONFIG_NUM_STAGES_MASK, - tegra210_mbdrc_band_params_get, tegra210_mbdrc_band_params_put), + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), TEGRA_SOC_BYTES_EXT("mbdrc in attack tc", TEGRA210_MBDRC_IN_ATTACK, TEGRA210_MBDRC_FILTER_COUNT, TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT, TEGRA210_MBDRC_IN_ATTACK_TC_MASK, - tegra210_mbdrc_band_params_get, tegra210_mbdrc_band_params_put), + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), TEGRA_SOC_BYTES_EXT("mbdrc in release tc", TEGRA210_MBDRC_IN_RELEASE, TEGRA210_MBDRC_FILTER_COUNT, TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT, TEGRA210_MBDRC_IN_RELEASE_TC_MASK, - tegra210_mbdrc_band_params_get, tegra210_mbdrc_band_params_put), + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), TEGRA_SOC_BYTES_EXT("mbdrc fast attack tc", TEGRA210_MBDRC_FAST_ATTACK, TEGRA210_MBDRC_FILTER_COUNT, TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT, TEGRA210_MBDRC_FAST_ATTACK_TC_MASK, - tegra210_mbdrc_band_params_get, tegra210_mbdrc_band_params_put), + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), TEGRA_SOC_BYTES_EXT("mbdrc in threshold", TEGRA210_MBDRC_IN_THRESHOLD, TEGRA210_MBDRC_FILTER_COUNT * 4, 0, 0xffffffff, - tegra210_mbdrc_threshold_get, tegra210_mbdrc_threshold_put), + tegra210_mbdrc_threshold_get, tegra210_mbdrc_threshold_put, tegra210_mbdrc_param_info), TEGRA_SOC_BYTES_EXT("mbdrc out threshold", TEGRA210_MBDRC_OUT_THRESHOLD, TEGRA210_MBDRC_FILTER_COUNT * 4, 0, 0xffffffff, - tegra210_mbdrc_threshold_get, tegra210_mbdrc_threshold_put), + tegra210_mbdrc_threshold_get, tegra210_mbdrc_threshold_put, tegra210_mbdrc_param_info), TEGRA_SOC_BYTES_EXT("mbdrc ratio", TEGRA210_MBDRC_RATIO_1ST, TEGRA210_MBDRC_FILTER_COUNT * 5, TEGRA210_MBDRC_RATIO_1ST_SHIFT, TEGRA210_MBDRC_RATIO_1ST_MASK, - tegra210_mbdrc_band_params_get, tegra210_mbdrc_band_params_put), - + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), TEGRA_SOC_BYTES_EXT("mbdrc makeup gain", TEGRA210_MBDRC_MAKEUP_GAIN, TEGRA210_MBDRC_FILTER_COUNT, TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT, TEGRA210_MBDRC_MAKEUP_GAIN_MASK, - tegra210_mbdrc_band_params_get, tegra210_mbdrc_band_params_put), + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), TEGRA_SOC_BYTES_EXT("mbdrc init gain", TEGRA210_MBDRC_INIT_GAIN, TEGRA210_MBDRC_FILTER_COUNT, TEGRA210_MBDRC_INIT_GAIN_SHIFT, TEGRA210_MBDRC_INIT_GAIN_MASK, - tegra210_mbdrc_band_params_get, tegra210_mbdrc_band_params_put), + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), TEGRA_SOC_BYTES_EXT("mbdrc attack gain", TEGRA210_MBDRC_GAIN_ATTACK, TEGRA210_MBDRC_FILTER_COUNT, TEGRA210_MBDRC_GAIN_ATTACK_SHIFT, TEGRA210_MBDRC_GAIN_ATTACK_MASK, - tegra210_mbdrc_band_params_get, tegra210_mbdrc_band_params_put), + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), TEGRA_SOC_BYTES_EXT("mbdrc release gain", TEGRA210_MBDRC_GAIN_RELEASE, TEGRA210_MBDRC_FILTER_COUNT, TEGRA210_MBDRC_GAIN_RELEASE_SHIFT, TEGRA210_MBDRC_GAIN_RELEASE_MASK, - tegra210_mbdrc_band_params_get, tegra210_mbdrc_band_params_put), + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), TEGRA_SOC_BYTES_EXT("mbdrc fast release gain", TEGRA210_MBDRC_FAST_RELEASE, TEGRA210_MBDRC_FILTER_COUNT, TEGRA210_MBDRC_FAST_RELEASE_SHIFT, TEGRA210_MBDRC_FAST_RELEASE_MASK, - tegra210_mbdrc_band_params_get, tegra210_mbdrc_band_params_put), + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), TEGRA_SOC_BYTES_EXT("mbdrc low band biquad coeffs", TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL, TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff, tegra210_mbdrc_biquad_coeffs_get, - tegra210_mbdrc_biquad_coeffs_put), + tegra210_mbdrc_biquad_coeffs_put, + tegra210_mbdrc_param_info), TEGRA_SOC_BYTES_EXT("mbdrc mid band biquad coeffs", TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL + TEGRA210_MBDRC_FILTER_PARAM_STRIDE, TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff, tegra210_mbdrc_biquad_coeffs_get, - tegra210_mbdrc_biquad_coeffs_put), + tegra210_mbdrc_biquad_coeffs_put, + tegra210_mbdrc_param_info), TEGRA_SOC_BYTES_EXT("mbdrc high band biquad coeffs", TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL + (TEGRA210_MBDRC_FILTER_PARAM_STRIDE * 2), TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff, tegra210_mbdrc_biquad_coeffs_get, - tegra210_mbdrc_biquad_coeffs_put), + tegra210_mbdrc_biquad_coeffs_put, + tegra210_mbdrc_param_info), }; static bool tegra210_mbdrc_wr_reg(struct device *dev, unsigned int reg) diff --git a/sound/soc/tegra-alt/tegra210_ope_alt.c b/sound/soc/tegra-alt/tegra210_ope_alt.c index 0b00c783..57ec66d3 100644 --- a/sound/soc/tegra-alt/tegra210_ope_alt.c +++ b/sound/soc/tegra-alt/tegra210_ope_alt.c @@ -1,7 +1,7 @@ /* * tegra210_ope_alt.c - Tegra210 OPE driver * - * Copyright (c) 2014-2016 NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -161,6 +161,13 @@ static int tegra210_ope_codec_probe(struct snd_soc_codec *codec) return 0; } +static struct regmap *tegra210_ope_init_regmap(struct device *dev) +{ + struct tegra210_ope *ope = dev_get_drvdata(dev); + + return ope->regmap; +} + static struct snd_soc_dai_ops tegra210_ope_dai_ops = { .hw_params = tegra210_ope_hw_params, }; @@ -222,6 +229,7 @@ static struct snd_soc_codec_driver tegra210_ope_codec = { .controls = tegra210_ope_controls, .num_controls = ARRAY_SIZE(tegra210_ope_controls), .idle_bias_off = 1, + .get_regmap = tegra210_ope_init_regmap, }; static bool tegra210_ope_wr_reg(struct device *dev, unsigned int reg) diff --git a/sound/soc/tegra-alt/tegra210_peq_alt.c b/sound/soc/tegra-alt/tegra210_peq_alt.c index 49ff4020..f456701a 100644 --- a/sound/soc/tegra-alt/tegra210_peq_alt.c +++ b/sound/soc/tegra-alt/tegra210_peq_alt.c @@ -1,7 +1,7 @@ /* * tegra210_peq_alt.c - Tegra210 PEQ driver * - * Copyright (c) 2014 NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -68,6 +68,8 @@ static const u32 biquad_init_shifts[TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH] = { 28, /* post-shift */ }; +static s32 biquad_coeff_buffer[TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH]; + static int tegra210_peq_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -111,9 +113,19 @@ static int tegra210_peq_ahub_ram_get(struct snd_kcontrol *kcontrol, { struct tegra_soc_bytes *params = (void *)kcontrol->private_value; struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - u32 *data = (u32 *)ucontrol->value.bytes.data; + struct tegra210_ope *ope = snd_soc_codec_get_drvdata(codec); + u32 i, reg_ctrl = params->soc.base; + u32 reg_data = reg_ctrl + codec->component.val_bytes; + s32 *data = (s32 *)biquad_coeff_buffer; + + pm_runtime_get_sync(codec->dev); + tegra210_xbar_read_ahubram(ope->peq_regmap, reg_ctrl, reg_data, + params->shift, data, params->soc.num_regs); + pm_runtime_put_sync(codec->dev); + + for (i = 0; i < params->soc.num_regs; i++) + ucontrol->value.integer.value[i] = (long)data[i]; - memset(data, 0, params->soc.num_regs * codec->component.val_bytes); return 0; } @@ -123,12 +135,31 @@ static int tegra210_peq_ahub_ram_put(struct snd_kcontrol *kcontrol, struct tegra_soc_bytes *params = (void *)kcontrol->private_value; struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct tegra210_ope *ope = snd_soc_codec_get_drvdata(codec); - u32 reg_ctrl = params->soc.base; + u32 i, reg_ctrl = params->soc.base; u32 reg_data = reg_ctrl + codec->component.val_bytes; - u32 *data = (u32 *)ucontrol->value.bytes.data; + s32 *data = (s32 *)biquad_coeff_buffer; + for (i = 0; i < params->soc.num_regs; i++) + data[i] = (s32)ucontrol->value.integer.value[i]; + + pm_runtime_get_sync(codec->dev); tegra210_xbar_write_ahubram(ope->peq_regmap, reg_ctrl, reg_data, params->shift, data, params->soc.num_regs); + pm_runtime_put_sync(codec->dev); + + return 0; +} + +static int tegra210_peq_param_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct soc_bytes *params = (void *)kcontrol->private_value; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->value.integer.min = -0x7fffffff; + uinfo->value.integer.max = 0x7fffffff; + uinfo->count = params->num_regs; + return 0; } @@ -137,14 +168,16 @@ static int tegra210_peq_ahub_ram_put(struct snd_kcontrol *kcontrol, TEGRA210_PEQ_AHUBRAMCTL_CONFIG_RAM_CTRL, \ TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH, \ (TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH * chan), 0xffffffff, \ - tegra210_peq_ahub_ram_get, tegra210_peq_ahub_ram_put) + tegra210_peq_ahub_ram_get, tegra210_peq_ahub_ram_put, \ + tegra210_peq_param_info) #define TEGRA210_PEQ_SHIFT_PARAMS_CTRL(chan) \ TEGRA_SOC_BYTES_EXT("peq channel" #chan " biquad shift params", \ TEGRA210_PEQ_AHUBRAMCTL_CONFIG_RAM_SHIFT_CTRL, \ TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH, \ (TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH * chan), 0x1f, \ - tegra210_peq_ahub_ram_get, tegra210_peq_ahub_ram_put) + tegra210_peq_ahub_ram_get, tegra210_peq_ahub_ram_put, \ + tegra210_peq_param_info) static const struct snd_kcontrol_new tegra210_peq_controls[] = { SOC_SINGLE_EXT("peq active", TEGRA210_PEQ_CONFIG, @@ -157,9 +190,21 @@ static const struct snd_kcontrol_new tegra210_peq_controls[] = { TEGRA210_PEQ_GAIN_PARAMS_CTRL(0), TEGRA210_PEQ_GAIN_PARAMS_CTRL(1), + TEGRA210_PEQ_GAIN_PARAMS_CTRL(2), + TEGRA210_PEQ_GAIN_PARAMS_CTRL(3), + TEGRA210_PEQ_GAIN_PARAMS_CTRL(4), + TEGRA210_PEQ_GAIN_PARAMS_CTRL(5), + TEGRA210_PEQ_GAIN_PARAMS_CTRL(6), + TEGRA210_PEQ_GAIN_PARAMS_CTRL(7), TEGRA210_PEQ_SHIFT_PARAMS_CTRL(0), TEGRA210_PEQ_SHIFT_PARAMS_CTRL(1), + TEGRA210_PEQ_SHIFT_PARAMS_CTRL(2), + TEGRA210_PEQ_SHIFT_PARAMS_CTRL(3), + TEGRA210_PEQ_SHIFT_PARAMS_CTRL(4), + TEGRA210_PEQ_SHIFT_PARAMS_CTRL(5), + TEGRA210_PEQ_SHIFT_PARAMS_CTRL(6), + TEGRA210_PEQ_SHIFT_PARAMS_CTRL(7), }; static bool tegra210_peq_wr_reg(struct device *dev, unsigned int reg)