From patchwork Mon Jul 7 11:56:09 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bard Liao X-Patchwork-Id: 4494491 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id D9FE6BEEAA for ; Mon, 7 Jul 2014 11:56:51 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C86D22021F for ; Mon, 7 Jul 2014 11:56:50 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 228EE2017E for ; Mon, 7 Jul 2014 11:56:49 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 0E1472651F0; Mon, 7 Jul 2014 13:56:47 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id 679BE2651C0; Mon, 7 Jul 2014 13:56:42 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 37DDA2651CE; Mon, 7 Jul 2014 13:56:41 +0200 (CEST) Received: from rtits2.realtek.com (rtits2.realtek.com [60.250.210.242]) by alsa0.perex.cz (Postfix) with ESMTP id 5D8D82651AF for ; Mon, 7 Jul 2014 13:56:32 +0200 (CEST) X-SpamFilter-By: BOX Solutions SpamTrap 5.39 with qID s67BuPbB026071, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtitcas11.realtek.com.tw[172.21.6.12]) by rtits2.realtek.com (8.14.5/2.37/5.60) with ESMTP id s67BuPbB026071 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT); Mon, 7 Jul 2014 19:56:25 +0800 Received: from sw-server.rtdomain (172.21.81.164) by RTITCAS11.realtek.com.tw (172.21.6.12) with Microsoft SMTP Server id 14.3.181.6; Mon, 7 Jul 2014 19:56:26 +0800 From: To: , Date: Mon, 7 Jul 2014 19:56:09 +0800 Message-ID: <1404734169-21766-1-git-send-email-bardliao@realtek.com> X-Mailer: git-send-email 1.8.1.1.439.g50a6b54 MIME-Version: 1.0 X-Originating-IP: [172.21.81.164] Cc: oder_chiou@realtek.com, Bard Liao , alsa-devel@alsa-project.org, lars@metafoo.de, flove@realtek.com Subject: [alsa-devel] [PATCH v2] ASoC: rt5640: add ASRC support X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP From: Bard Liao This patch add ASRC support for rt5640 series codecs. Signed-off-by: Bard Liao --- sound/soc/codecs/rt5640.c | 79 ++++++++++++++++++++++++++++++++++++++++++++--- sound/soc/codecs/rt5640.h | 3 ++ 2 files changed, 78 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 6bc6efd..494b1b4 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -1020,9 +1020,45 @@ 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); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (rt5640->asrc_en[RT5640_AIF1] || + rt5640->asrc_en[RT5640_AIF2]) { + snd_soc_update_bits(w->codec, + RT5640_DUMMY1, 0x70, 0x70); + snd_soc_update_bits(w->codec, + RT5640_JD_CTRL, 0x3, 0x3); + 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); + snd_soc_update_bits(w->codec, + RT5640_JD_CTRL, 0x3, 0); + snd_soc_update_bits(w->codec, + RT5640_DUMMY1, 0x70, 0); + 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 +1312,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"}, @@ -1636,10 +1675,17 @@ static int rt5640_hw_params(struct snd_pcm_substream *substream, rt5640->lrck[dai->id] = params_rate(params); 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); - return -EINVAL; + if ((rt5640->bclk_ratio[dai->id] != 64 && + rt5640->bclk_ratio[dai->id] != 32) || pre_div < 0) { + if (rt5640->sysclk < rt5640->lrck[dai->id] * 384) { + dev_err(codec->dev, "Unsupported clock setting"); + return -EINVAL; + } + dev_info(codec->dev, "Use ASRC\n"); + rt5640->asrc_en[dai->id] = true; + pre_div = 0; + } else { + rt5640->asrc_en[dai->id] = false; } frame_size = snd_soc_params_to_frame_size(params); if (frame_size < 0) { @@ -1698,6 +1744,17 @@ static int rt5640_hw_params(struct snd_pcm_substream *substream, return 0; } +static int rt5640_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); + + rt5640->asrc_en[dai->id] = false; + + return 0; +} + static int rt5640_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct snd_soc_codec *codec = dai->codec; @@ -1864,6 +1921,16 @@ static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, return 0; } +static int rt5640_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) +{ + struct snd_soc_codec *codec = dai->codec; + struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); + + rt5640->bclk_ratio[dai->id] = ratio; + + return 0; +} + static int rt5640_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { @@ -1995,9 +2062,11 @@ static int rt5640_resume(struct snd_soc_codec *codec) static const struct snd_soc_dai_ops rt5640_aif_dai_ops = { .hw_params = rt5640_hw_params, + .hw_free = rt5640_hw_free, .set_fmt = rt5640_set_dai_fmt, .set_sysclk = rt5640_set_dai_sysclk, .set_pll = rt5640_set_dai_pll, + .set_bclk_ratio = rt5640_set_bclk_ratio, }; static struct snd_soc_dai_driver rt5640_dai[] = { @@ -2214,6 +2283,8 @@ static int rt5640_i2c_probe(struct i2c_client *i2c, } rt5640->hp_mute = 1; + rt5640->bclk_ratio[RT5640_AIF1] = 64; + rt5640->bclk_ratio[RT5640_AIF2] = 64; return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640, rt5640_dai, ARRAY_SIZE(rt5640_dai)); diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h index 58ebe96..63b465d 100644 --- a/sound/soc/codecs/rt5640.h +++ b/sound/soc/codecs/rt5640.h @@ -2095,6 +2095,9 @@ struct rt5640_priv { int pll_out; bool hp_mute; + + bool asrc_en[RT5640_AIFS]; + int bclk_ratio[RT5640_AIFS]; }; #endif