From: <derek.fang@realtek.com>
To: <broonie@kernel.org>, <lgirdwood@gmail.com>
Cc: oder_chiou@realtek.com, jack.yu@realtek.com,
alsa-devel@alsa-project.org, lars@metafoo.de,
kent_chen@realtek.com, derek.fang@realtek.com,
shumingf@realtek.com, flove@realtek.com
Subject: [PATCH 2/2] ASoC: rt1015: Fix the failure to flush DAC data before playback
Date: Mon, 14 Sep 2020 16:57:19 +0800 [thread overview]
Message-ID: <1600073839-6762-2-git-send-email-derek.fang@realtek.com> (raw)
In-Reply-To: <1600073839-6762-1-git-send-email-derek.fang@realtek.com>
From: "derek.fang" <derek.fang@realtek.com>
Fix the failure to flush DAC data before playback.
Signed-off-by: derek.fang <derek.fang@realtek.com>
---
sound/soc/codecs/rt1015.c | 63 +++++++++++++++++++++++++++++++++++++++++------
sound/soc/codecs/rt1015.h | 7 ++++++
2 files changed, 63 insertions(+), 7 deletions(-)
diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c
index ba1b6b3..25fe2dd 100644
--- a/sound/soc/codecs/rt1015.c
+++ b/sound/soc/codecs/rt1015.c
@@ -534,6 +534,32 @@ static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol,
return 0;
}
+static void rt1015_flush_work(struct work_struct *work)
+{
+ struct rt1015_priv *rt1015 = container_of(work, struct rt1015_priv,
+ flush_work.work);
+ struct snd_soc_component *component = rt1015->component;
+ unsigned int val, i = 0, count = 20;
+
+ while (i < count) {
+ usleep_range(1000, 1500);
+ dev_dbg(component->dev, "Flush DAC (retry:%u)\n", i);
+ regmap_read(rt1015->regmap, RT1015_CLK_DET, &val);
+ if (val & 0x800)
+ break;
+ i++;
+ }
+
+ regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x0597);
+ regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x05f7);
+ regmap_write(rt1015->regmap, RT1015_MAN_I2C, 0x0028);
+
+ if (val & 0x800)
+ dev_dbg(component->dev, "Flush DAC completed.\n");
+ else
+ dev_warn(component->dev, "Fail to flush DAC data.\n");
+}
+
static const struct snd_kcontrol_new rt1015_snd_controls[] = {
SOC_SINGLE_TLV("DAC Playback Volume", RT1015_DAC1, RT1015_DAC_VOL_SFT,
127, 0, dac_vol_tlv),
@@ -587,12 +613,7 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w,
break;
case SND_SOC_DAPM_POST_PMU:
- if (rt1015->bypass_boost == RT1015_Bypass_Boost) {
- regmap_write(rt1015->regmap, RT1015_MAN_I2C, 0x00a8);
- regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x0597);
- regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x05f7);
- regmap_write(rt1015->regmap, RT1015_MAN_I2C, 0x0028);
- }
+ regmap_write(rt1015->regmap, RT1015_MAN_I2C, 0x00a8);
break;
case SND_SOC_DAPM_POST_PMD:
@@ -608,6 +629,8 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w,
RT1015_SYS_RST1, 0x05f5);
}
rt1015->dac_is_used = 0;
+
+ cancel_delayed_work_sync(&rt1015->flush_work);
break;
default:
@@ -616,6 +639,24 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w,
return 0;
}
+static int rt1015_amp_drv_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_component *component =
+ snd_soc_dapm_to_component(w->dapm);
+ struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ if (rt1015->hw_config == RT1015_HW_28)
+ schedule_delayed_work(&rt1015->flush_work, msecs_to_jiffies(10));
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
static const struct snd_soc_dapm_widget rt1015_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("LDO2", RT1015_PWR1, RT1015_PWR_LDO2_BIT, 0,
NULL, 0),
@@ -649,6 +690,8 @@ static const struct snd_soc_dapm_widget rt1015_dapm_widgets[] = {
r1015_dac_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_OUT_DRV_E("Amp Drv", SND_SOC_NOPM, 0, 0, NULL, 0,
+ rt1015_amp_drv_event, SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_OUTPUT("SPO"),
};
@@ -667,7 +710,8 @@ static const struct snd_soc_dapm_route rt1015_dapm_routes[] = {
{ "DAC", NULL, "MIXERV" },
{ "DAC", NULL, "SUMV" },
{ "DAC", NULL, "VREFLV" },
- { "SPO", NULL, "DAC" },
+ { "Amp Drv", NULL, "DAC" },
+ { "SPO", NULL, "Amp Drv" },
};
static int rt1015_hw_params(struct snd_pcm_substream *substream,
@@ -910,6 +954,8 @@ static int rt1015_probe(struct snd_soc_component *component)
rt1015->cali_done = 0;
snd_soc_component_write(component, RT1015_BAT_RPO_STEP1, 0x061c);
+ INIT_DELAYED_WORK(&rt1015->flush_work, rt1015_flush_work);
+
return 0;
}
@@ -917,6 +963,7 @@ static void rt1015_remove(struct snd_soc_component *component)
{
struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component);
+ cancel_delayed_work_sync(&rt1015->flush_work);
regmap_write(rt1015->regmap, RT1015_RESET, 0);
}
@@ -1042,6 +1089,8 @@ static int rt1015_i2c_probe(struct i2c_client *i2c,
return ret;
}
+ rt1015->hw_config = (i2c->addr == 0x29) ? RT1015_HW_29 : RT1015_HW_28;
+
regmap_read(rt1015->regmap, RT1015_DEVICE_ID, &val);
if ((val != RT1015_DEVICE_ID_VAL) && (val != RT1015_DEVICE_ID_VAL2)) {
dev_err(&i2c->dev,
diff --git a/sound/soc/codecs/rt1015.h b/sound/soc/codecs/rt1015.h
index 4d11f58..d3fdd30 100644
--- a/sound/soc/codecs/rt1015.h
+++ b/sound/soc/codecs/rt1015.h
@@ -373,6 +373,11 @@ enum {
RT1015_Bypass_Boost,
};
+enum {
+ RT1015_HW_28 = 0,
+ RT1015_HW_29,
+};
+
struct rt1015_priv {
struct snd_soc_component *component;
struct regmap *regmap;
@@ -390,6 +395,8 @@ struct rt1015_priv {
int amp_ver;
int dac_is_used;
int cali_done;
+ int hw_config;
+ struct delayed_work flush_work;
};
#endif /* __RT1015_H__ */
--
2.7.4
next prev parent reply other threads:[~2020-09-14 8:59 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-14 8:57 [PATCH 1/2] ASoC: rt1015: Fix DC calibration on bypass boost mode derek.fang
2020-09-14 8:57 ` derek.fang [this message]
2020-09-14 14:51 ` Mark Brown
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=1600073839-6762-2-git-send-email-derek.fang@realtek.com \
--to=derek.fang@realtek.com \
--cc=alsa-devel@alsa-project.org \
--cc=broonie@kernel.org \
--cc=flove@realtek.com \
--cc=jack.yu@realtek.com \
--cc=kent_chen@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