From a60f494128a70d6697015ec7387a95d341361ec4 Mon Sep 17 00:00:00 2001 From: "yujie.wu" Date: Fri, 15 Mar 2019 10:13:02 +0800 Subject: [PATCH] audio: Add Mute function for tas5782 [1/1] PD#SWPL-5961 Problem: There is no mute control for tas5782 Solution: Add mute function for tas 5782 Verify: A113 Change-Id: I75f8b82a359778f28494636fe76c7bc4db848643 Signed-off-by: yujie.wu --- sound/soc/codecs/amlogic/tas5782m.c | 141 ++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/sound/soc/codecs/amlogic/tas5782m.c b/sound/soc/codecs/amlogic/tas5782m.c index 4befae2..d7bbfe3 100644 --- a/sound/soc/codecs/amlogic/tas5782m.c +++ b/sound/soc/codecs/amlogic/tas5782m.c @@ -52,6 +52,7 @@ static void tas5782m_late_resume(struct early_suspend *h); SNDRV_PCM_FMTBIT_S32_LE) #define TAS5782M_REG_00 (0x00) +#define TAS5782M_REG_03 (0x03) #define TAS5782M_REG_7F (0x7F) #define TAS5782M_REG_28 (0x28) #define TAS5782M_REG_29 (0x29) @@ -85,6 +86,8 @@ struct tas5782m_priv { struct soc_enum eq_conf_enum; unsigned char Ch1_vol; unsigned char Ch2_vol; + unsigned char Ch1_mute; + unsigned char Ch2_mute; unsigned char master_vol; unsigned int mclk; unsigned int EQ_enum_value; @@ -127,6 +130,38 @@ static int tas5782m_ch2_vol_info(struct snd_kcontrol *kcontrol, } +static int tas5782m_ch1_mute_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->access = SNDRV_CTL_ELEM_ACCESS_TLV_READ + | SNDRV_CTL_ELEM_ACCESS_READWRITE; + uinfo->count = 1; + + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + uinfo->value.integer.step = 1; + + return 0; +} + +static int tas5782m_ch2_mute_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->access = SNDRV_CTL_ELEM_ACCESS_TLV_READ + | SNDRV_CTL_ELEM_ACCESS_READWRITE; + uinfo->count = 1; + + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + uinfo->value.integer.step = 1; + + return 0; +} + + + static int tas5782m_ch1_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -150,6 +185,29 @@ static int tas5782m_ch2_vol_get(struct snd_kcontrol *kcontrol, } +static int tas5782m_ch1_mute_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tas5782m_priv *tas5782m = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = tas5782m->Ch1_mute; + + return 0; +} + +static int tas5782m_ch2_mute_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tas5782m_priv *tas5782m = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = tas5782m->Ch2_mute; + + return 0; +} + + static void tas5782m_set_volume(struct snd_soc_codec *codec, int value, int ch_num) { @@ -198,6 +256,7 @@ static int tas5782m_ch1_vol_put(struct snd_kcontrol *kcontrol, value = ucontrol->value.integer.value[0]; tas5782m->Ch1_vol = value; + value = 255 - value; tas5782m_set_volume(codec, value, 0); return 0; @@ -212,11 +271,78 @@ static int tas5782m_ch2_vol_put(struct snd_kcontrol *kcontrol, value = ucontrol->value.integer.value[0]; tas5782m->Ch2_vol = value; + value = 255 - value; tas5782m_set_volume(codec, value, 1); return 0; } +static void tas5782m_set_mute(struct snd_soc_codec *codec, + unsigned char left_mute, + unsigned char right_mute) +{ + unsigned char buf[2]; + int write_count = 0; + struct tas5782m_priv *tas5782m = snd_soc_codec_get_drvdata(codec); + + + buf[0] = TAS5782M_REG_00, buf[1] = 0x00; + write_count = 2; + if (write_count != i2c_master_send(tas5782m->i2c, buf, write_count)) + pr_err("%s %d !!!!! i2c_master_send error !!!!!\n", + __func__, __LINE__); + + buf[0] = TAS5782M_REG_7F, buf[1] = 0x00; + write_count = 2; + if (write_count != i2c_master_send(tas5782m->i2c, buf, write_count)) + pr_err("%s %d !!!!! i2c_master_send error !!!!!\n", + __func__, __LINE__); + + buf[0] = TAS5782M_REG_00, buf[1] = 0x00; + write_count = 2; + if (write_count != i2c_master_send(tas5782m->i2c, buf, write_count)) + pr_err("%s %d !!!!! i2c_master_send error !!!!!\n", + __func__, __LINE__); + + buf[0] = TAS5782M_REG_03; + buf[1] = left_mute << 4 | right_mute; + write_count = 2; + if (write_count != i2c_master_send(tas5782m->i2c, buf, write_count)) + pr_err("%s %d !!!!! i2c_master_send error !!!!!\n", + __func__, __LINE__); + +} + + +static int tas5782m_ch1_mute_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tas5782m_priv *tas5782m = snd_soc_codec_get_drvdata(codec); + int value; + + value = ucontrol->value.integer.value[0]; + tas5782m->Ch1_mute = value; + tas5782m_set_mute(codec, tas5782m->Ch1_mute, tas5782m->Ch2_mute); + + return 0; +} + +static int tas5782m_ch2_mute_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tas5782m_priv *tas5782m = snd_soc_codec_get_drvdata(codec); + int value; + + value = ucontrol->value.integer.value[0]; + tas5782m->Ch2_mute = value; + tas5782m_set_mute(codec, tas5782m->Ch1_mute, tas5782m->Ch2_mute); + + return 0; +} + + static const struct snd_kcontrol_new tas5782m_snd_controls[] = { { @@ -232,7 +358,22 @@ static const struct snd_kcontrol_new tas5782m_snd_controls[] = { .info = tas5782m_ch2_vol_info, .get = tas5782m_ch2_vol_get, .put = tas5782m_ch2_vol_put, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Ch1 Mute", + .info = tas5782m_ch1_mute_info, + .get = tas5782m_ch1_mute_get, + .put = tas5782m_ch1_mute_set, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Ch2 Mute", + .info = tas5782m_ch2_mute_info, + .get = tas5782m_ch2_mute_get, + .put = tas5782m_ch2_mute_set, } + }; static int tas5782m_set_dai_sysclk(struct snd_soc_dai *codec_dai, -- 2.7.4