ASoC: mt6359: kselftest fix and driver extension
Merge series from Trevor Wu <trevor.wu@mediatek.com>: The patch series includes a kselftest fix and changes for extending driver capability to support more use cases.
This commit is contained in:
commit
ad45067aa5
@ -18,6 +18,20 @@
|
||||
|
||||
#include "mt6359.h"
|
||||
|
||||
static void mt6359_set_gpio_smt(struct mt6359_priv *priv)
|
||||
{
|
||||
/* set gpio SMT mode */
|
||||
regmap_update_bits(priv->regmap, MT6359_SMT_CON1, 0x3ff0, 0x3ff0);
|
||||
}
|
||||
|
||||
static void mt6359_set_gpio_driving(struct mt6359_priv *priv)
|
||||
{
|
||||
/* 8:4mA(default), a:8mA, c:12mA, e:16mA */
|
||||
regmap_update_bits(priv->regmap, MT6359_DRV_CON2, 0xffff, 0x8888);
|
||||
regmap_update_bits(priv->regmap, MT6359_DRV_CON3, 0xffff, 0x8888);
|
||||
regmap_update_bits(priv->regmap, MT6359_DRV_CON4, 0x00ff, 0x88);
|
||||
}
|
||||
|
||||
static void mt6359_set_playback_gpio(struct mt6359_priv *priv)
|
||||
{
|
||||
/* set gpio mosi mode, clk / data mosi */
|
||||
@ -360,8 +374,34 @@ static int mt6359_put_volsw(struct snd_kcontrol *kcontrol,
|
||||
(struct soc_mixer_control *)kcontrol->private_value;
|
||||
unsigned int reg = 0;
|
||||
int index = ucontrol->value.integer.value[0];
|
||||
int orig_gain[2], new_gain[2];
|
||||
int ret;
|
||||
|
||||
switch (mc->reg) {
|
||||
case MT6359_ZCD_CON2:
|
||||
orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL];
|
||||
orig_gain[1] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTR];
|
||||
break;
|
||||
case MT6359_ZCD_CON1:
|
||||
orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTL];
|
||||
orig_gain[1] = priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTR];
|
||||
break;
|
||||
case MT6359_ZCD_CON3:
|
||||
orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTL];
|
||||
break;
|
||||
case MT6359_AUDENC_ANA_CON0:
|
||||
orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP1];
|
||||
break;
|
||||
case MT6359_AUDENC_ANA_CON1:
|
||||
orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP2];
|
||||
break;
|
||||
case MT6359_AUDENC_ANA_CON2:
|
||||
orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP3];
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = snd_soc_put_volsw(kcontrol, ucontrol);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -373,6 +413,8 @@ static int mt6359_put_volsw(struct snd_kcontrol *kcontrol,
|
||||
(reg >> RG_AUDHPLGAIN_SFT) & RG_AUDHPLGAIN_MASK;
|
||||
priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTR] =
|
||||
(reg >> RG_AUDHPRGAIN_SFT) & RG_AUDHPRGAIN_MASK;
|
||||
new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL];
|
||||
new_gain[1] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTR];
|
||||
break;
|
||||
case MT6359_ZCD_CON1:
|
||||
regmap_read(priv->regmap, MT6359_ZCD_CON1, ®);
|
||||
@ -380,35 +422,82 @@ static int mt6359_put_volsw(struct snd_kcontrol *kcontrol,
|
||||
(reg >> RG_AUDLOLGAIN_SFT) & RG_AUDLOLGAIN_MASK;
|
||||
priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTR] =
|
||||
(reg >> RG_AUDLORGAIN_SFT) & RG_AUDLORGAIN_MASK;
|
||||
new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTL];
|
||||
new_gain[1] = priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTR];
|
||||
break;
|
||||
case MT6359_ZCD_CON3:
|
||||
regmap_read(priv->regmap, MT6359_ZCD_CON3, ®);
|
||||
priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTL] =
|
||||
(reg >> RG_AUDHSGAIN_SFT) & RG_AUDHSGAIN_MASK;
|
||||
new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTL];
|
||||
break;
|
||||
case MT6359_AUDENC_ANA_CON0:
|
||||
regmap_read(priv->regmap, MT6359_AUDENC_ANA_CON0, ®);
|
||||
priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP1] =
|
||||
(reg >> RG_AUDPREAMPLGAIN_SFT) & RG_AUDPREAMPLGAIN_MASK;
|
||||
new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP1];
|
||||
break;
|
||||
case MT6359_AUDENC_ANA_CON1:
|
||||
regmap_read(priv->regmap, MT6359_AUDENC_ANA_CON1, ®);
|
||||
priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP2] =
|
||||
(reg >> RG_AUDPREAMPRGAIN_SFT) & RG_AUDPREAMPRGAIN_MASK;
|
||||
new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP2];
|
||||
break;
|
||||
case MT6359_AUDENC_ANA_CON2:
|
||||
regmap_read(priv->regmap, MT6359_AUDENC_ANA_CON2, ®);
|
||||
priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP3] =
|
||||
(reg >> RG_AUDPREAMP3GAIN_SFT) & RG_AUDPREAMP3GAIN_MASK;
|
||||
new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP3];
|
||||
break;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
if (orig_gain[0] != new_gain[0]) {
|
||||
ret = 1;
|
||||
} else if (snd_soc_volsw_is_stereo(mc)) {
|
||||
if (orig_gain[1] != new_gain[1])
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
dev_dbg(priv->dev, "%s(), name %s, reg(0x%x) = 0x%x, set index = %x\n",
|
||||
__func__, kcontrol->id.name, mc->reg, reg, index);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mt6359_get_playback_volsw(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_kcontrol_component(kcontrol);
|
||||
struct mt6359_priv *priv = snd_soc_component_get_drvdata(component);
|
||||
struct soc_mixer_control *mc =
|
||||
(struct soc_mixer_control *)kcontrol->private_value;
|
||||
|
||||
switch (mc->reg) {
|
||||
case MT6359_ZCD_CON2:
|
||||
ucontrol->value.integer.value[0] =
|
||||
priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL];
|
||||
ucontrol->value.integer.value[1] =
|
||||
priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTR];
|
||||
break;
|
||||
case MT6359_ZCD_CON1:
|
||||
ucontrol->value.integer.value[0] =
|
||||
priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTL];
|
||||
ucontrol->value.integer.value[1] =
|
||||
priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTR];
|
||||
break;
|
||||
case MT6359_ZCD_CON3:
|
||||
ucontrol->value.integer.value[0] =
|
||||
priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTL];
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* MUX */
|
||||
|
||||
/* LOL MUX */
|
||||
@ -1070,9 +1159,10 @@ static int mt_lo_event(struct snd_soc_dapm_widget *w,
|
||||
{
|
||||
struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
|
||||
struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);
|
||||
unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]);
|
||||
|
||||
dev_dbg(priv->dev, "%s(), event 0x%x, mux %u\n",
|
||||
__func__, event, dapm_kcontrol_get_value(w->kcontrols[0]));
|
||||
__func__, event, mux);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
@ -1110,14 +1200,29 @@ static int mt_lo_event(struct snd_soc_dapm_widget *w,
|
||||
/* Enable AUD_CLK */
|
||||
mt6359_set_decoder_clk(priv, true);
|
||||
|
||||
/* Enable Audio DAC (3rd DAC) */
|
||||
regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON7, 0x3113);
|
||||
/* Enable low-noise mode of DAC */
|
||||
if (priv->dev_counter[DEVICE_HP] == 0)
|
||||
regmap_write(priv->regmap,
|
||||
MT6359_AUDDEC_ANA_CON9, 0x0001);
|
||||
/* Switch LOL MUX to audio 3rd DAC */
|
||||
regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON7, 0x311b);
|
||||
/* Switch LOL MUX to audio DAC */
|
||||
if (mux == LO_MUX_L_DAC) {
|
||||
if (priv->dev_counter[DEVICE_HP] > 0) {
|
||||
dev_info(priv->dev, "%s(), can not enable DAC, hp count %d\n",
|
||||
__func__, priv->dev_counter[DEVICE_HP]);
|
||||
break;
|
||||
}
|
||||
/* Enable DACL and switch HP MUX to open*/
|
||||
regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON0, 0x3009);
|
||||
/* Disable low-noise mode of DAC */
|
||||
regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON9, 0xf200);
|
||||
usleep_range(100, 120);
|
||||
/* Switch LOL MUX to DACL */
|
||||
regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON7, 0x0117);
|
||||
} else if (mux == LO_MUX_3RD_DAC) {
|
||||
/* Enable Audio DAC (3rd DAC) */
|
||||
regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON7, 0x3113);
|
||||
/* Enable low-noise mode of DAC */
|
||||
if (priv->dev_counter[DEVICE_HP] == 0)
|
||||
regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON9, 0x0001);
|
||||
/* Switch LOL MUX to audio 3rd DAC */
|
||||
regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON7, 0x311b);
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
/* Switch LOL MUX to open */
|
||||
@ -1129,6 +1234,15 @@ static int mt_lo_event(struct snd_soc_dapm_widget *w,
|
||||
regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON0,
|
||||
0x000f, 0x0000);
|
||||
|
||||
if (mux == LO_MUX_L_DAC) {
|
||||
/* Disable HP driver core circuits */
|
||||
regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON0,
|
||||
0x3 << 4, 0x0);
|
||||
/* Disable HP driver bias circuits */
|
||||
regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON0,
|
||||
0x3 << 6, 0x0);
|
||||
}
|
||||
|
||||
/* Disable AUD_CLK */
|
||||
mt6359_set_decoder_clk(priv, false);
|
||||
|
||||
@ -2358,6 +2472,10 @@ static const struct snd_soc_dapm_route mt6359_dapm_routes[] = {
|
||||
{"MISO2_MUX", "UL2_CH1", "UL2_SRC_MUX"},
|
||||
{"MISO2_MUX", "UL2_CH2", "UL2_SRC_MUX"},
|
||||
|
||||
{"MISO0_MUX", NULL, "UL_SRC"},
|
||||
{"MISO1_MUX", NULL, "UL_SRC"},
|
||||
{"MISO2_MUX", NULL, "UL_SRC_34"},
|
||||
|
||||
{"UL_SRC_MUX", "AMIC", "ADC_L"},
|
||||
{"UL_SRC_MUX", "AMIC", "ADC_R"},
|
||||
{"UL_SRC_MUX", "DMIC", "DMIC0_MUX"},
|
||||
@ -2497,6 +2615,7 @@ static const struct snd_soc_dapm_route mt6359_dapm_routes[] = {
|
||||
|
||||
/* Lineout Path */
|
||||
{"LOL Mux", "Playback", "DAC_3RD"},
|
||||
{"LOL Mux", "Playback_L_DAC", "DACL"},
|
||||
{"LINEOUT L", NULL, "LOL Mux"},
|
||||
|
||||
/* Headphone Path */
|
||||
@ -2666,6 +2785,8 @@ static int mt6359_codec_init_reg(struct snd_soc_component *cmpnt)
|
||||
0x1 << RG_AUDLOLSCDISABLE_VAUDP32_SFT);
|
||||
|
||||
/* set gpio */
|
||||
mt6359_set_gpio_smt(priv);
|
||||
mt6359_set_gpio_driving(priv);
|
||||
mt6359_reset_playback_gpio(priv);
|
||||
mt6359_reset_capture_gpio(priv);
|
||||
|
||||
@ -2697,22 +2818,23 @@ static void mt6359_codec_remove(struct snd_soc_component *cmpnt)
|
||||
cmpnt->regmap = NULL;
|
||||
}
|
||||
|
||||
static const DECLARE_TLV_DB_SCALE(hp_playback_tlv, -2200, 100, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(playback_tlv, -1000, 100, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(capture_tlv, 0, 600, 0);
|
||||
|
||||
static const struct snd_kcontrol_new mt6359_snd_controls[] = {
|
||||
/* dl pga gain */
|
||||
SOC_DOUBLE_EXT_TLV("Headset Volume",
|
||||
MT6359_ZCD_CON2, 0, 7, 0x1E, 0,
|
||||
snd_soc_get_volsw, mt6359_put_volsw,
|
||||
hp_playback_tlv),
|
||||
MT6359_ZCD_CON2, 0, 7, 0x12, 0,
|
||||
mt6359_get_playback_volsw, mt6359_put_volsw,
|
||||
playback_tlv),
|
||||
SOC_DOUBLE_EXT_TLV("Lineout Volume",
|
||||
MT6359_ZCD_CON1, 0, 7, 0x12, 0,
|
||||
snd_soc_get_volsw, mt6359_put_volsw, playback_tlv),
|
||||
mt6359_get_playback_volsw, mt6359_put_volsw,
|
||||
playback_tlv),
|
||||
SOC_SINGLE_EXT_TLV("Handset Volume",
|
||||
MT6359_ZCD_CON3, 0, 0x12, 0,
|
||||
snd_soc_get_volsw, mt6359_put_volsw, playback_tlv),
|
||||
mt6359_get_playback_volsw, mt6359_put_volsw,
|
||||
playback_tlv),
|
||||
|
||||
/* ul pga gain */
|
||||
SOC_SINGLE_EXT_TLV("PGA1 Volume",
|
||||
|
Loading…
x
Reference in New Issue
Block a user