summaryrefslogtreecommitdiff
path: root/asoc/codecs/wcd934x
diff options
context:
space:
mode:
authorVidyakumar Athota <vathota@codeaurora.org>2017-12-20 14:20:40 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2018-02-28 21:48:57 -0800
commit9147e38e71b9853edcdb19bc32bf6727c9f795b8 (patch)
tree897f7cfd3a942e04b0b56c49752c19e3de437556 /asoc/codecs/wcd934x
parentda56c67bc43cbf42d1004d9e1499fbe9a28f3dd2 (diff)
downloadmsm-extra-9147e38e71b9853edcdb19bc32bf6727c9f795b8.tar.gz
asoc: codecs: update IIR cofficient values before IIR band enable
Currently IIR coefficient values are written to HW everytime when digital core comes out of power collapse. This increases playback cold start latency. So update IIR coefficient values before IIR band enable. Change-Id: I57ad54b4674ed0a49fdfc55d77c519568f5a7893 Signed-off-by: Vidyakumar Athota <vathota@codeaurora.org>
Diffstat (limited to 'asoc/codecs/wcd934x')
-rw-r--r--asoc/codecs/wcd934x/wcd934x.c87
1 files changed, 50 insertions, 37 deletions
diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c
index e7cec2b4..c584ea7c 100644
--- a/asoc/codecs/wcd934x/wcd934x.c
+++ b/asoc/codecs/wcd934x/wcd934x.c
@@ -127,6 +127,7 @@ static const struct snd_kcontrol_new name##_mux = \
#define WCD934X_STRING_LEN 100
#define WCD934X_CDC_SIDETONE_IIR_COEFF_MAX 5
+#define WCD934X_CDC_REPEAT_WRITES_MAX 16
#define WCD934X_DIG_CORE_REG_MIN WCD934X_CDC_ANC0_CLK_RESET_CTL
#define WCD934X_DIG_CORE_REG_MAX 0xFFF
@@ -628,8 +629,8 @@ struct tavil_priv {
struct tavil_idle_detect_config idle_det_cfg;
int power_active_ref;
- int sidetone_coeff_array[IIR_MAX][BAND_MAX]
- [WCD934X_CDC_SIDETONE_IIR_COEFF_MAX];
+ u8 sidetone_coeff_array[IIR_MAX][BAND_MAX]
+ [WCD934X_CDC_SIDETONE_IIR_COEFF_MAX * 4];
struct spi_device *spi;
struct platform_device *pdev_child_devices
@@ -4927,6 +4928,36 @@ static int tavil_codec_reset_hph_registers(struct snd_soc_dapm_widget *w,
return 0;
}
+static void tavil_restore_iir_coeff(struct tavil_priv *tavil, int iir_idx,
+ int band_idx)
+{
+ u16 reg_add;
+ int no_of_reg = 0;
+
+ regmap_write(tavil->wcd9xxx->regmap,
+ (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
+ (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
+
+ reg_add = WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx;
+
+ if (tavil->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
+ return;
+ /*
+ * Since wcd9xxx_slim_write_repeat() supports only maximum of 16
+ * registers at a time, split total 20 writes(5 coefficients per
+ * band and 4 writes per coefficient) into 16 and 4.
+ */
+ no_of_reg = WCD934X_CDC_REPEAT_WRITES_MAX;
+ wcd9xxx_slim_write_repeat(tavil->wcd9xxx, reg_add, no_of_reg,
+ &tavil->sidetone_coeff_array[iir_idx][band_idx][0]);
+
+ no_of_reg = (WCD934X_CDC_SIDETONE_IIR_COEFF_MAX * 4) -
+ WCD934X_CDC_REPEAT_WRITES_MAX;
+ wcd9xxx_slim_write_repeat(tavil->wcd9xxx, reg_add, no_of_reg,
+ &tavil->sidetone_coeff_array[iir_idx][band_idx]
+ [WCD934X_CDC_REPEAT_WRITES_MAX]);
+}
+
static int tavil_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -4951,6 +4982,7 @@ static int tavil_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
int iir_idx = ((struct soc_multi_mixer_control *)
kcontrol->private_value)->reg;
int band_idx = ((struct soc_multi_mixer_control *)
@@ -4959,6 +4991,8 @@ static int tavil_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol,
int value = ucontrol->value.integer.value[0];
u16 iir_reg = WCD934X_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx;
+ tavil_restore_iir_coeff(tavil, iir_idx, band_idx);
+
/* Mask first 5 bits, 6-8 are reserved */
snd_soc_update_bits(codec, iir_reg, (1 << band_idx),
(value << band_idx));
@@ -5085,7 +5119,7 @@ static int tavil_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol,
kcontrol->private_value)->reg;
int band_idx = ((struct soc_multi_mixer_control *)
kcontrol->private_value)->shift;
- int coeff_idx;
+ int coeff_idx, idx = 0;
/*
* Mask top bit it is reserved
@@ -5098,11 +5132,19 @@ static int tavil_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol,
/* Store the coefficients in sidetone coeff array */
for (coeff_idx = 0; coeff_idx < WCD934X_CDC_SIDETONE_IIR_COEFF_MAX;
coeff_idx++) {
- tavil->sidetone_coeff_array[iir_idx][band_idx][coeff_idx] =
- ucontrol->value.integer.value[coeff_idx];
- set_iir_band_coeff(codec, iir_idx, band_idx,
- tavil->sidetone_coeff_array[iir_idx][band_idx]
- [coeff_idx]);
+ uint32_t value = ucontrol->value.integer.value[coeff_idx];
+
+ set_iir_band_coeff(codec, iir_idx, band_idx, value);
+
+ /* Four 8 bit values(one 32 bit) per coefficient */
+ tavil->sidetone_coeff_array[iir_idx][band_idx][idx++] =
+ (value & 0xFF);
+ tavil->sidetone_coeff_array[iir_idx][band_idx][idx++] =
+ (value >> 8) & 0xFF;
+ tavil->sidetone_coeff_array[iir_idx][band_idx][idx++] =
+ (value >> 16) & 0xFF;
+ tavil->sidetone_coeff_array[iir_idx][band_idx][idx++] =
+ (value >> 24) & 0xFF;
}
pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
@@ -5123,33 +5165,6 @@ static int tavil_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol,
return 0;
}
-static void tavil_restore_iir_coeff(struct tavil_priv *tavil, int iir_idx)
-{
- int band_idx = 0, coeff_idx = 0;
- struct snd_soc_codec *codec = tavil->codec;
-
- /*
- * snd_soc_write call crashes at rmmod if there is no machine
- * driver and hence no codec pointer available
- */
- if (!codec)
- return;
-
- for (band_idx = 0; band_idx < BAND_MAX; band_idx++) {
- snd_soc_write(codec,
- (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
- (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
-
- for (coeff_idx = 0;
- coeff_idx < WCD934X_CDC_SIDETONE_IIR_COEFF_MAX;
- coeff_idx++) {
- set_iir_band_coeff(codec, iir_idx, band_idx,
- tavil->sidetone_coeff_array[iir_idx][band_idx]
- [coeff_idx]);
- }
- }
-}
-
static int tavil_compander_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -8250,8 +8265,6 @@ static int tavil_dig_core_remove_power_collapse(struct tavil_priv *tavil)
WCD934X_DIG_CORE_REG_MIN,
WCD934X_DIG_CORE_REG_MAX);
- tavil_restore_iir_coeff(tavil, IIR0);
- tavil_restore_iir_coeff(tavil, IIR1);
return 0;
}