[alsa-devel] [PATCH] ASoC: rt5640: add ASRC support
bardliao at realtek.com
bardliao at realtek.com
Fri Jun 27 12:58:11 CEST 2014
From: Bard Liao <bardliao at realtek.com>
This patch add ASRC support for rt5640 series codecs.
Signed-off-by: Bard Liao <bardliao at realtek.com>
---
sound/soc/codecs/rt5640.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++-
sound/soc/codecs/rt5640.h | 2 ++
2 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 6bc6efd..3245ec4 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -341,6 +341,43 @@ static bool rt5640_readable_register(struct device *dev, unsigned int reg)
}
}
+static const char * const rt5640_asrc_mode[] = {
+ "disable", "enable"
+};
+
+static const SOC_ENUM_SINGLE_DECL(rt5640_asrc_enum, SND_SOC_NOPM,
+ 0, rt5640_asrc_mode);
+
+static int rt5640_asrc_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+
+ rt5640->asrc_en = ucontrol->value.integer.value[0];
+
+ if (rt5640->asrc_en) {
+ snd_soc_update_bits(codec, RT5640_DUMMY1, 0x70, 0x70);
+ snd_soc_update_bits(codec, RT5640_JD_CTRL, 0x3, 0x3);
+ } else {
+ snd_soc_update_bits(codec, RT5640_DUMMY1, 0x70, 0x0);
+ snd_soc_update_bits(codec, RT5640_JD_CTRL, 0x3, 0x0);
+ }
+
+ return 0;
+}
+
+static int rt5640_asrc_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = rt5640->asrc_en;
+
+ return 0;
+}
+
static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
@@ -436,6 +473,10 @@ static const struct snd_kcontrol_new rt5640_snd_controls[] = {
SOC_ENUM("DAC IF1 Data Switch", rt5640_if1_dac_enum),
SOC_ENUM("ADC IF2 Data Switch", rt5640_if2_adc_enum),
SOC_ENUM("DAC IF2 Data Switch", rt5640_if2_dac_enum),
+
+ /* ASRC */
+ SOC_ENUM_EXT("ASRC Switch", rt5640_asrc_enum,
+ rt5640_asrc_get, rt5640_asrc_put),
};
static const struct snd_kcontrol_new rt5640_specific_snd_controls[] = {
@@ -1020,9 +1061,37 @@ static int rt5640_hp_post_event(struct snd_soc_dapm_widget *w,
return 0;
}
+static int rt5640_asrc_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(w->codec);
+
+ if (!rt5640->asrc_en)
+ return 0;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_write(w->codec, RT5640_ASRC_1, 0x9b00);
+ snd_soc_write(w->codec, RT5640_ASRC_2, 0xf800);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_write(w->codec, RT5640_ASRC_1, 0x0);
+ snd_soc_write(w->codec, RT5640_ASRC_2, 0x0);
+ break;
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("PLL1", RT5640_PWR_ANLG2,
RT5640_PWR_PLL_BIT, 0, NULL, 0),
+
+ SND_SOC_DAPM_SUPPLY_S("ASRC Function", 1, SND_SOC_NOPM,
+ 0, 0, rt5640_asrc_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
/* Input Side */
/* micbias */
SND_SOC_DAPM_SUPPLY("LDO2", RT5640_PWR_ANLG1,
@@ -1276,6 +1345,9 @@ static const struct snd_soc_dapm_widget rt5639_specific_dapm_widgets[] = {
};
static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
+ {"I2S1", NULL, "ASRC Function"},
+ {"I2S2", NULL, "ASRC Function"},
+
{"IN1P", NULL, "LDO2"},
{"IN2P", NULL, "LDO2"},
@@ -1635,7 +1707,12 @@ static int rt5640_hw_params(struct snd_pcm_substream *substream,
int dai_sel, pre_div, bclk_ms, frame_size;
rt5640->lrck[dai->id] = params_rate(params);
- pre_div = rl6231_get_clk_info(rt5640->sysclk, rt5640->lrck[dai->id]);
+ if (rt5640->asrc_en)
+ pre_div = 0;
+ else
+ pre_div = rl6231_get_clk_info(rt5640->sysclk,
+ rt5640->lrck[dai->id]);
+
if (pre_div < 0) {
dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n",
rt5640->lrck[dai->id], dai->id);
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index 58ebe96..0b39178 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -2095,6 +2095,8 @@ struct rt5640_priv {
int pll_out;
bool hp_mute;
+
+ int asrc_en;
};
#endif
--
1.8.1.1.439.g50a6b54
More information about the Alsa-devel
mailing list