From bdb8fa6b09a801a6cbe3c2487f0228860f9c5aba Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Tue, 7 May 2019 18:12:18 +0800 Subject: ASoC: mediatek: mt6358: initialize setting when ramping volume Mt6358 ramps up from the smallest volume (i.e. -10dB) to target dB when opening and ramps down from target dB to mute (i.e. -40dB) when closing. If target is equal to -10dB when opening, headset_volume_ramp() simply leaves current setting (which may not be -10dB) unchanged. Execute the loop at least once to initialize the setting to the starting point (i.e. from). Signed-off-by: Tzung-Bi Shih Signed-off-by: Mark Brown --- sound/soc/codecs/mt6358.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/mt6358.c b/sound/soc/codecs/mt6358.c index d4c4fee6d3d9..96547ae50a5d 100644 --- a/sound/soc/codecs/mt6358.c +++ b/sound/soc/codecs/mt6358.c @@ -405,10 +405,9 @@ static bool is_valid_hp_pga_idx(int reg_idx) reg_idx == DL_GAIN_N_40DB; } -static void headset_volume_ramp(struct mt6358_priv *priv, - int from, int to) +static void headset_volume_ramp(struct mt6358_priv *priv, int from, int to) { - int offset = 0, count = 1, reg_idx; + int offset = 0, count = 0, reg_idx; if (!is_valid_hp_pga_idx(from) || !is_valid_hp_pga_idx(to)) dev_warn(priv->dev, "%s(), volume index is not valid, from %d, to %d\n", @@ -422,7 +421,7 @@ static void headset_volume_ramp(struct mt6358_priv *priv, else offset = from - to; - while (offset > 0) { + while (offset >= 0) { if (to > from) reg_idx = from + count; else -- cgit v1.2.3-59-g8ed1b From bbb56537a3279f7221e253afc29e834a3d99662f Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Tue, 7 May 2019 18:12:19 +0800 Subject: ASoC: mediatek: mt6358: save output volume for mixer controls Output volume settings from mixer controls would be lost. Imagine that "Headphone Volume" has set to -10dB via amixer: - in mtk_hp_enable() - hp_store_gain() saves the volume setting -10dB from regmap_read() to ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL] - headset_volume_ramp() ramps up from -10dB to -10dB - in mtk_hp_disable() - headset_volume_ramp() ramps down from -10dB to -40dB Next time in mtk_hp_enable(), hp_store_gain() would save -40dB but not -10dB. As a result, headset_volume_ramp() would ramp from -10dB to -40dB (which is mute). Signed-off-by: Tzung-Bi Shih Signed-off-by: Mark Brown --- sound/soc/codecs/mt6358.c | 91 ++++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 40 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/mt6358.c b/sound/soc/codecs/mt6358.c index 96547ae50a5d..44edbda8afcc 100644 --- a/sound/soc/codecs/mt6358.c +++ b/sound/soc/codecs/mt6358.c @@ -320,32 +320,6 @@ enum { #define DL_GAIN_N_40DB_REG (DL_GAIN_N_40DB << 7 | DL_GAIN_N_40DB) #define DL_GAIN_REG_MASK 0x0f9f -static void lo_store_gain(struct mt6358_priv *priv) -{ - unsigned int reg; - unsigned int gain_l, gain_r; - - regmap_read(priv->regmap, MT6358_ZCD_CON1, ®); - gain_l = (reg >> RG_AUDLOLGAIN_SFT) & RG_AUDLOLGAIN_MASK; - gain_r = (reg >> RG_AUDLORGAIN_SFT) & RG_AUDLORGAIN_MASK; - - priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTL] = gain_l; - priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTR] = gain_r; -} - -static void hp_store_gain(struct mt6358_priv *priv) -{ - unsigned int reg; - unsigned int gain_l, gain_r; - - regmap_read(priv->regmap, MT6358_ZCD_CON2, ®); - gain_l = (reg >> RG_AUDHPLGAIN_SFT) & RG_AUDHPLGAIN_MASK; - gain_r = (reg >> RG_AUDHPRGAIN_SFT) & RG_AUDHPRGAIN_MASK; - - priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL] = gain_l; - priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTR] = gain_r; -} - static void hp_zcd_disable(struct mt6358_priv *priv) { regmap_write(priv->regmap, MT6358_ZCD_CON0, 0x0000); @@ -439,20 +413,62 @@ static void headset_volume_ramp(struct mt6358_priv *priv, int from, int to) } } +static int mt6358_put_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct mt6358_priv *priv = snd_soc_component_get_drvdata(component); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + unsigned int reg; + int ret; + + ret = snd_soc_put_volsw(kcontrol, ucontrol); + if (ret < 0) + return ret; + + switch (mc->reg) { + case MT6358_ZCD_CON2: + regmap_read(priv->regmap, MT6358_ZCD_CON2, ®); + priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL] = + (reg >> RG_AUDHPLGAIN_SFT) & RG_AUDHPLGAIN_MASK; + priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTR] = + (reg >> RG_AUDHPRGAIN_SFT) & RG_AUDHPRGAIN_MASK; + break; + case MT6358_ZCD_CON1: + regmap_read(priv->regmap, MT6358_ZCD_CON1, ®); + priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTL] = + (reg >> RG_AUDLOLGAIN_SFT) & RG_AUDLOLGAIN_MASK; + priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTR] = + (reg >> RG_AUDLORGAIN_SFT) & RG_AUDLORGAIN_MASK; + break; + case MT6358_ZCD_CON3: + regmap_read(priv->regmap, MT6358_ZCD_CON3, ®); + priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTL] = + (reg >> RG_AUDHSGAIN_SFT) & RG_AUDHSGAIN_MASK; + priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTR] = + (reg >> RG_AUDHSGAIN_SFT) & RG_AUDHSGAIN_MASK; + break; + } + + return ret; +} + static const DECLARE_TLV_DB_SCALE(playback_tlv, -1000, 100, 0); static const DECLARE_TLV_DB_SCALE(pga_tlv, 0, 600, 0); static const struct snd_kcontrol_new mt6358_snd_controls[] = { /* dl pga gain */ - SOC_DOUBLE_TLV("Headphone Volume", - MT6358_ZCD_CON2, 0, 7, 0x12, 1, - playback_tlv), - SOC_DOUBLE_TLV("Lineout Volume", - MT6358_ZCD_CON1, 0, 7, 0x12, 1, - playback_tlv), - SOC_SINGLE_TLV("Handset Volume", - MT6358_ZCD_CON3, 0, 0x12, 1, - playback_tlv), + SOC_DOUBLE_EXT_TLV("Headphone Volume", + MT6358_ZCD_CON2, 0, 7, 0x12, 1, + snd_soc_get_volsw, mt6358_put_volsw, playback_tlv), + SOC_DOUBLE_EXT_TLV("Lineout Volume", + MT6358_ZCD_CON1, 0, 7, 0x12, 1, + snd_soc_get_volsw, mt6358_put_volsw, playback_tlv), + SOC_SINGLE_EXT_TLV("Handset Volume", + MT6358_ZCD_CON3, 0, 0x12, 1, + snd_soc_get_volsw, mt6358_put_volsw, playback_tlv), /* ul pga gain */ SOC_DOUBLE_R_TLV("PGA Volume", MT6358_AUDENC_ANA_CON0, MT6358_AUDENC_ANA_CON1, @@ -831,8 +847,6 @@ static int mtk_hp_enable(struct mt6358_priv *priv) /* Reduce ESD resistance of AU_REFN */ regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON2, 0x4000); - /* save target gain to restore after hardware open complete */ - hp_store_gain(priv); /* Set HPR/HPL gain as minimum (~ -40dB) */ regmap_write(priv->regmap, MT6358_ZCD_CON2, DL_GAIN_N_40DB_REG); @@ -1042,8 +1056,6 @@ static int mtk_hp_spk_enable(struct mt6358_priv *priv) /* Reduce ESD resistance of AU_REFN */ regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON2, 0x4000); - /* save target gain to restore after hardware open complete */ - hp_store_gain(priv); /* Set HPR/HPL gain to -10dB */ regmap_write(priv->regmap, MT6358_ZCD_CON2, DL_GAIN_N_10DB_REG); @@ -1103,7 +1115,6 @@ static int mtk_hp_spk_enable(struct mt6358_priv *priv) hp_main_output_ramp(priv, true); /* Set LO gain as minimum (~ -40dB) */ - lo_store_gain(priv); regmap_write(priv->regmap, MT6358_ZCD_CON1, DL_GAIN_N_40DB_REG); /* apply volume setting */ headset_volume_ramp(priv, -- cgit v1.2.3-59-g8ed1b From ec0574a6ce31f2d6640bb8a5edf98973356dd3b4 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Tue, 7 May 2019 18:12:20 +0800 Subject: ASoC: mediatek: mt6358: save PGA for mixer control mt6358_amic_disable() resets PGA to 0. Save the gain settings from mixer control and restore them when using the microphone. Signed-off-by: Tzung-Bi Shih Signed-off-by: Mark Brown --- sound/soc/codecs/mt6358.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/mt6358.c b/sound/soc/codecs/mt6358.c index 44edbda8afcc..50b3fc5457ea 100644 --- a/sound/soc/codecs/mt6358.c +++ b/sound/soc/codecs/mt6358.c @@ -450,6 +450,15 @@ static int mt6358_put_volsw(struct snd_kcontrol *kcontrol, priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTR] = (reg >> RG_AUDHSGAIN_SFT) & RG_AUDHSGAIN_MASK; break; + case MT6358_AUDENC_ANA_CON0: + case MT6358_AUDENC_ANA_CON1: + regmap_read(priv->regmap, MT6358_AUDENC_ANA_CON0, ®); + priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP1] = + (reg >> RG_AUDPREAMPLGAIN_SFT) & RG_AUDPREAMPLGAIN_MASK; + regmap_read(priv->regmap, MT6358_AUDENC_ANA_CON1, ®); + priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP2] = + (reg >> RG_AUDPREAMPRGAIN_SFT) & RG_AUDPREAMPRGAIN_MASK; + break; } return ret; @@ -470,10 +479,10 @@ static const struct snd_kcontrol_new mt6358_snd_controls[] = { MT6358_ZCD_CON3, 0, 0x12, 1, snd_soc_get_volsw, mt6358_put_volsw, playback_tlv), /* ul pga gain */ - SOC_DOUBLE_R_TLV("PGA Volume", - MT6358_AUDENC_ANA_CON0, MT6358_AUDENC_ANA_CON1, - 8, 4, 0, - pga_tlv), + SOC_DOUBLE_R_EXT_TLV("PGA Volume", + MT6358_AUDENC_ANA_CON0, MT6358_AUDENC_ANA_CON1, + 8, 4, 0, + snd_soc_get_volsw, mt6358_put_volsw, pga_tlv), }; /* MUX */ @@ -1750,6 +1759,21 @@ static void mt6358_dmic_disable(struct mt6358_priv *priv) regmap_write(priv->regmap, MT6358_AUDENC_ANA_CON9, 0x0000); } +static void mt6358_restore_pga(struct mt6358_priv *priv) +{ + unsigned int gain_l, gain_r; + + gain_l = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP1]; + gain_r = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP2]; + + regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON0, + RG_AUDPREAMPLGAIN_MASK_SFT, + gain_l << RG_AUDPREAMPLGAIN_SFT); + regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1, + RG_AUDPREAMPRGAIN_MASK_SFT, + gain_r << RG_AUDPREAMPRGAIN_SFT); +} + static int mt_mic_type_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -1774,6 +1798,7 @@ static int mt_mic_type_event(struct snd_soc_dapm_widget *w, mt6358_amic_enable(priv); break; } + mt6358_restore_pga(priv); break; case SND_SOC_DAPM_POST_PMD: -- cgit v1.2.3-59-g8ed1b From 939507f2779836919271ba0311723d1001d3993b Mon Sep 17 00:00:00 2001 From: Libin Yang Date: Tue, 7 May 2019 14:33:11 +0800 Subject: ASoC: codec: hdac_hdmi: no checking monitor in hw_params Some userspace apps, like pulseaudio, may call open, hw_params, prepare to judge whether the pcm is ready or not. Current hdac_hdmi will return -ENODEV if monitor is not connected, which will cause the apps believe the pcm is not ready. Actually PCM for hdmi is ready, even the monitor is not connected. This patch removes the check of monitor presence in hw_params, just like what the legacy HD-Audio driver does. Signed-off-by: Libin Yang Acked-by: Pierre-Louis Bossart Signed-off-by: Mark Brown --- sound/soc/codecs/hdac_hdmi.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index 4de1fbfa8827..660e0587f399 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -455,24 +455,11 @@ static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hparams, struct snd_soc_dai *dai) { struct hdac_hdmi_priv *hdmi = snd_soc_dai_get_drvdata(dai); - struct hdac_device *hdev = hdmi->hdev; struct hdac_hdmi_dai_port_map *dai_map; - struct hdac_hdmi_port *port; struct hdac_hdmi_pcm *pcm; int format; dai_map = &hdmi->dai_map[dai->id]; - port = dai_map->port; - - if (!port) - return -ENODEV; - - if ((!port->eld.monitor_present) || (!port->eld.eld_valid)) { - dev_err(&hdev->dev, - "device is not configured for this pin:port%d:%d\n", - port->pin->nid, port->id); - return -ENODEV; - } format = snd_hdac_calc_stream_format(params_rate(hparams), params_channels(hparams), params_format(hparams), -- cgit v1.2.3-59-g8ed1b From 4fc19fffaaf87335aafaeb059a561ef91aa6031c Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Mon, 6 May 2019 14:54:11 +0200 Subject: ASoC: stm32: i2s: update pcm hardware constraints - Set period minimum size. Ensure at least 5ms period up to 48kHz/16 bits to prevent underrun/overrun. - Remove MDMA constraints on period maximum size and set period maximum to half the buffer maximum size. Signed-off-by: Olivier Moysan Signed-off-by: Mark Brown --- sound/soc/stm/stm32_i2s.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c index 97d5e9901a0e..8ee697ff1f86 100644 --- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -731,7 +731,8 @@ static const struct snd_soc_dai_ops stm32_i2s_pcm_dai_ops = { static const struct snd_pcm_hardware stm32_i2s_pcm_hw = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP, .buffer_bytes_max = 8 * PAGE_SIZE, - .period_bytes_max = 2048, + .period_bytes_min = 1024, + .period_bytes_max = 4 * PAGE_SIZE, .periods_min = 2, .periods_max = 8, }; -- cgit v1.2.3-59-g8ed1b From 7f6647ced298d56027218e47619b7f0d925fc83e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 8 May 2019 10:50:37 +0200 Subject: ASoC: SOF: Fix unused variable warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The recent fix for the build fix caused a couple of unused variable compiler warnings when CONFIG_SND_SOC_SOF_NOCODEC isn't set: sound/soc/sof/core.c:263:6: warning: unused variable ‘ret’ [-Wunused-variable] sound/soc/sof/core.c:262:28: warning: unused variable ‘machine’ [-Wunused-variable] Fix them by adding another ifdef. Fixes: ce38a75089f7 ("ASoC: SOF: core: fix undefined nocodec reference") Signed-off-by: Takashi Iwai Signed-off-by: Mark Brown --- sound/soc/sof/core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound') diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 5ddbfa8f1a28..32105e0fabe8 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -259,8 +259,10 @@ int snd_sof_create_page_table(struct snd_sof_dev *sdev, static int sof_machine_check(struct snd_sof_dev *sdev) { struct snd_sof_pdata *plat_data = sdev->pdata; +#if IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC) struct snd_soc_acpi_mach *machine; int ret; +#endif if (plat_data->machine) return 0; -- cgit v1.2.3-59-g8ed1b