From: <jack.yu@realtek.com>
To: <broonie@kernel.org>, <lgirdwood@gmail.com>
Cc: oder_chiou@realtek.com, Jack Yu <jack.yu@realtek.com>,
alsa-devel@alsa-project.org, lars@metafoo.de,
derek.fang@realtek.com, flove@realtek.com, shumingf@realtek.com,
bard.liao@intel.com
Subject: [PATCH] ASoC: rt715: add main capture switch and main capture volume control
Date: Mon, 14 Dec 2020 14:49:03 +0800 [thread overview]
Message-ID: <20201214064903.2746-1-jack.yu@realtek.com> (raw)
From: Jack Yu <jack.yu@realtek.com>
Add main capture switch and main capture volume for callback to be in
single operation.
Signed-off-by: Jack Yu <jack.yu@realtek.com>
---
sound/soc/codecs/rt715.c | 174 +++++++++++++++++++++++----------------
1 file changed, 105 insertions(+), 69 deletions(-)
diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c
index 9a7d393d424a..cdcba70146da 100644
--- a/sound/soc/codecs/rt715.c
+++ b/sound/soc/codecs/rt715.c
@@ -80,85 +80,106 @@ static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol,
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);
+ unsigned int capture_reg_H[] = {RT715_SET_GAIN_MIC_ADC_H,
+ RT715_SET_GAIN_LINE_ADC_H, RT715_SET_GAIN_MIX_ADC_H,
+ RT715_SET_GAIN_MIX_ADC2_H};
+ unsigned int capture_reg_L[] = {RT715_SET_GAIN_MIC_ADC_L,
+ RT715_SET_GAIN_LINE_ADC_L, RT715_SET_GAIN_MIX_ADC_L,
+ RT715_SET_GAIN_MIX_ADC2_L};
unsigned int addr_h, addr_l, val_h, val_ll, val_lr;
- unsigned int read_ll, read_rl;
- int i;
-
- /* Can't use update bit function, so read the original value first */
- addr_h = mc->reg;
- addr_l = mc->rreg;
- if (mc->shift == RT715_DIR_OUT_SFT) /* output */
- val_h = 0x80;
- else /* input */
- val_h = 0x0;
-
- rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll);
+ unsigned int read_ll, read_rl, i, j, loop_cnt;
- /* L Channel */
- if (mc->invert) {
- /* for mute */
- val_ll = (mc->max - ucontrol->value.integer.value[0]) << 7;
- /* keep gain */
- read_ll = read_ll & 0x7f;
- val_ll |= read_ll;
- } else {
- /* for gain */
- val_ll = ((ucontrol->value.integer.value[0]) & 0x7f);
- if (val_ll > mc->max)
- val_ll = mc->max;
- /* keep mute status */
- read_ll = read_ll & 0x80;
- val_ll |= read_ll;
- }
-
- /* R Channel */
- if (mc->invert) {
- regmap_write(rt715->regmap,
- RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D0);
- /* for mute */
- val_lr = (mc->max - ucontrol->value.integer.value[1]) << 7;
- /* keep gain */
- read_rl = read_rl & 0x7f;
- val_lr |= read_rl;
- } else {
- /* for gain */
- val_lr = ((ucontrol->value.integer.value[1]) & 0x7f);
- if (val_lr > mc->max)
- val_lr = mc->max;
- /* keep mute status */
- read_rl = read_rl & 0x80;
- val_lr |= read_rl;
- }
-
- for (i = 0; i < 3; i++) { /* retry 3 times at most */
+ if (strstr(ucontrol->id.name, "Main Capture Switch") ||
+ strstr(ucontrol->id.name, "Main Capture Volume"))
+ loop_cnt = 4;
+ else
+ loop_cnt = 1;
- if (val_ll == val_lr) {
- /* Set both L/R channels at the same time */
- val_h = (1 << mc->shift) | (3 << 4);
- regmap_write(rt715->regmap, addr_h,
- (val_h << 8 | val_ll));
- regmap_write(rt715->regmap, addr_l,
- (val_h << 8 | val_ll));
+ for (j = 0; j < loop_cnt; j++) {
+ /* Can't use update bit function, so read the original value first */
+ if (loop_cnt == 1) {
+ addr_h = mc->reg;
+ addr_l = mc->rreg;
} else {
- /* Lch*/
- val_h = (1 << mc->shift) | (1 << 5);
- regmap_write(rt715->regmap, addr_h,
- (val_h << 8 | val_ll));
- /* Rch */
- val_h = (1 << mc->shift) | (1 << 4);
- regmap_write(rt715->regmap, addr_l,
- (val_h << 8 | val_lr));
+ addr_h = capture_reg_H[j];
+ addr_l = capture_reg_L[j];
}
- /* check result */
+
if (mc->shift == RT715_DIR_OUT_SFT) /* output */
val_h = 0x80;
else /* input */
val_h = 0x0;
- rt715_get_gain(rt715, addr_h, addr_l, val_h,
- &read_rl, &read_ll);
- if (read_rl == val_lr && read_ll == val_ll)
- break;
+ rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll);
+
+ if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)
+ regmap_write(rt715->regmap,
+ RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D0);
+
+ /* L Channel */
+ if (mc->invert) {
+ /* for mute */
+ val_ll = (mc->max - ucontrol->value.integer.value[0]) << 7;
+ /* keep gain */
+ read_ll = read_ll & 0x7f;
+ val_ll |= read_ll;
+ } else {
+ /* for gain */
+ val_ll = ((ucontrol->value.integer.value[0]) & 0x7f);
+ if (val_ll > mc->max)
+ val_ll = mc->max;
+ /* keep mute status */
+ read_ll = read_ll & 0x80;
+ val_ll |= read_ll;
+ }
+
+ /* R Channel */
+ if (mc->invert) {
+ /* for mute */
+ val_lr = (mc->max - ucontrol->value.integer.value[1]) << 7;
+ /* keep gain */
+ read_rl = read_rl & 0x7f;
+ val_lr |= read_rl;
+ } else {
+ /* for gain */
+ val_lr = ((ucontrol->value.integer.value[1]) & 0x7f);
+ if (val_lr > mc->max)
+ val_lr = mc->max;
+ /* keep mute status */
+ read_rl = read_rl & 0x80;
+ val_lr |= read_rl;
+ }
+
+ for (i = 0; i < 3; i++) { /* retry 3 times at most */
+
+ if (val_ll == val_lr) {
+ /* Set both L/R channels at the same time */
+ val_h = (1 << mc->shift) | (3 << 4);
+ regmap_write(rt715->regmap, addr_h,
+ (val_h << 8 | val_ll));
+ regmap_write(rt715->regmap, addr_l,
+ (val_h << 8 | val_ll));
+ } else {
+ /* Lch*/
+ val_h = (1 << mc->shift) | (1 << 5);
+ regmap_write(rt715->regmap, addr_h,
+ (val_h << 8 | val_ll));
+ /* Rch */
+ val_h = (1 << mc->shift) | (1 << 4);
+ regmap_write(rt715->regmap, addr_l,
+ (val_h << 8 | val_lr));
+ }
+ /* check result */
+ if (mc->shift == RT715_DIR_OUT_SFT) /* output */
+ val_h = 0x80;
+ else /* input */
+ val_h = 0x0;
+
+ rt715_get_gain(rt715, addr_h, addr_l, val_h,
+ &read_rl, &read_ll);
+ if (read_rl == val_lr && read_ll == val_ll)
+ break;
+ }
}
/* D0:power on state, D3: power saving mode */
if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)
@@ -226,6 +247,13 @@ static const struct snd_kcontrol_new rt715_snd_controls[] = {
SOC_DOUBLE_R_EXT("ADC 27 Capture Switch", RT715_SET_GAIN_MIX_ADC2_H,
RT715_SET_GAIN_MIX_ADC2_L, RT715_DIR_IN_SFT, 1, 1,
rt715_set_amp_gain_get, rt715_set_amp_gain_put),
+ /*
+ * "Main Capture Switch" looks the same as "ADC 07 Capture Switch",
+ * but the callback has different action internally.
+ */
+ SOC_DOUBLE_R_EXT("Main Capture Switch", RT715_SET_GAIN_MIC_ADC_H,
+ RT715_SET_GAIN_MIC_ADC_L, RT715_DIR_IN_SFT, 1, 1,
+ rt715_set_amp_gain_get, rt715_set_amp_gain_put),
/* Volume Control */
SOC_DOUBLE_R_EXT_TLV("ADC 07 Capture Volume", RT715_SET_GAIN_MIC_ADC_H,
RT715_SET_GAIN_MIC_ADC_L, RT715_DIR_IN_SFT, 0x3f, 0,
@@ -243,6 +271,14 @@ static const struct snd_kcontrol_new rt715_snd_controls[] = {
RT715_SET_GAIN_MIX_ADC2_L, RT715_DIR_IN_SFT, 0x3f, 0,
rt715_set_amp_gain_get, rt715_set_amp_gain_put,
in_vol_tlv),
+ /*
+ * "Main Capture Volume" looks the same as "ADC 07 Capture Volume",
+ * but the callback has different action internally.
+ */
+ SOC_DOUBLE_R_EXT_TLV("Main Capture Volume", RT715_SET_GAIN_MIC_ADC_H,
+ RT715_SET_GAIN_MIC_ADC_L, RT715_DIR_IN_SFT, 0x3f, 0,
+ rt715_set_amp_gain_get, rt715_set_amp_gain_put,
+ in_vol_tlv),
/* MIC Boost Control */
SOC_DOUBLE_R_EXT_TLV("DMIC1 Boost", RT715_SET_GAIN_DMIC1_H,
RT715_SET_GAIN_DMIC1_L, RT715_DIR_IN_SFT, 3, 0,
--
2.29.0
next reply other threads:[~2020-12-14 6:50 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-14 6:49 jack.yu [this message]
2020-12-14 7:35 ` [PATCH] ASoC: rt715: add main capture switch and main capture volume control Jaroslav Kysela
2020-12-14 15:07 ` Pierre-Louis Bossart
2020-12-14 16:44 ` Jaroslav Kysela
2020-12-14 16:58 ` Takashi Iwai
2020-12-14 17:12 ` Pierre-Louis Bossart
2020-12-15 10:39 ` Jaroslav Kysela
2020-12-15 16:00 ` Pierre-Louis Bossart
2020-12-15 16:27 ` Jaroslav Kysela
2020-12-15 17:05 ` Pierre-Louis Bossart
2020-12-15 17:31 ` Jaroslav Kysela
2021-01-05 8:11 ` Jack Yu
2021-01-06 9:39 ` Yang, Libin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201214064903.2746-1-jack.yu@realtek.com \
--to=jack.yu@realtek.com \
--cc=alsa-devel@alsa-project.org \
--cc=bard.liao@intel.com \
--cc=broonie@kernel.org \
--cc=derek.fang@realtek.com \
--cc=flove@realtek.com \
--cc=lars@metafoo.de \
--cc=lgirdwood@gmail.com \
--cc=oder_chiou@realtek.com \
--cc=shumingf@realtek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox