[alsa-devel] [PATCH 1/4] ASoC: rt5645: Redefine format config for rt5650
rt5650 and rt5645 use different register bits for format configuration. This patch modifies rt5645_hw_params and rt5645_set_dai_fmt to support both codecs.
Signed-off-by: Bard Liao bardliao@realtek.com --- Mark,
I am think if we should use different codec driver for rt5645 and rt5650. In fact, they are different Die. What do you think?
--- --- sound/soc/codecs/rt5645.c | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-)
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 4c384a1..0133c8c 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -2049,7 +2049,7 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_codec *codec = dai->codec; struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); - unsigned int val_len = 0, val_clk, mask_clk; + unsigned int val_len = 0, val_clk, mask_clk, dl_sft; int pre_div, bclk_ms, frame_size;
rt5645->lrck[dai->id] = params_rate(params); @@ -2063,6 +2063,16 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream, dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size); return -EINVAL; } + + switch (rt5645->codec_type) { + case CODEC_TYPE_RT5650: + dl_sft = 4; + break; + default: + dl_sft = 2; + break; + } + bclk_ms = frame_size > 32; rt5645->bclk[dai->id] = rt5645->lrck[dai->id] * (32 << bclk_ms);
@@ -2075,13 +2085,13 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream, case 16: break; case 20: - val_len |= RT5645_I2S_DL_20; + val_len = 0x1; break; case 24: - val_len |= RT5645_I2S_DL_24; + val_len = 0x2; break; case 8: - val_len |= RT5645_I2S_DL_8; + val_len = 0x3; break; default: return -EINVAL; @@ -2093,7 +2103,7 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream, val_clk = bclk_ms << RT5645_I2S_BCLK_MS1_SFT | pre_div << RT5645_I2S_PD1_SFT; snd_soc_update_bits(codec, RT5645_I2S1_SDP, - RT5645_I2S_DL_MASK, val_len); + (0x3 << dl_sft), (val_len << dl_sft)); snd_soc_update_bits(codec, RT5645_ADDA_CLK1, mask_clk, val_clk); break; case RT5645_AIF2: @@ -2101,7 +2111,7 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream, val_clk = bclk_ms << RT5645_I2S_BCLK_MS2_SFT | pre_div << RT5645_I2S_PD2_SFT; snd_soc_update_bits(codec, RT5645_I2S2_SDP, - RT5645_I2S_DL_MASK, val_len); + (0x3 << dl_sft), (val_len << dl_sft)); snd_soc_update_bits(codec, RT5645_ADDA_CLK1, mask_clk, val_clk); break; default: @@ -2116,7 +2126,16 @@ static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct snd_soc_codec *codec = dai->codec; struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); - unsigned int reg_val = 0; + unsigned int reg_val = 0, pol_sft; + + switch (rt5645->codec_type) { + case CODEC_TYPE_RT5650: + pol_sft = 8; + break; + default: + pol_sft = 7; + break; + }
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: @@ -2134,7 +2153,7 @@ static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) case SND_SOC_DAIFMT_NB_NF: break; case SND_SOC_DAIFMT_IB_NF: - reg_val |= RT5645_I2S_BP_INV; + reg_val |= (1 << pol_sft); break; default: return -EINVAL; @@ -2158,12 +2177,12 @@ static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) switch (dai->id) { case RT5645_AIF1: snd_soc_update_bits(codec, RT5645_I2S1_SDP, - RT5645_I2S_MS_MASK | RT5645_I2S_BP_MASK | + RT5645_I2S_MS_MASK | (1 << pol_sft) | RT5645_I2S_DF_MASK, reg_val); break; case RT5645_AIF2: snd_soc_update_bits(codec, RT5645_I2S2_SDP, - RT5645_I2S_MS_MASK | RT5645_I2S_BP_MASK | + RT5645_I2S_MS_MASK | (1 << pol_sft) | RT5645_I2S_DF_MASK, reg_val); break; default:
RT5645 doesn't support auto incrementing writes so driver should set the use_single_rw flag for regmap.
Signed-off-by: Bard Liao bardliao@realtek.com --- sound/soc/codecs/rt5645.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 0133c8c..f9edf09 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -2633,7 +2633,7 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5645 = { static const struct regmap_config rt5645_regmap = { .reg_bits = 8, .val_bits = 16, - + .use_single_rw = true, .max_register = RT5645_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5645_ranges) * RT5645_PR_SPACING), .volatile_reg = rt5645_volatile_register,
In codec bias level off, we need to disable gate mode with MCLK for power saving. It is set by one bit. We don't need to write while register for that.
Signed-off-by: Bard Liao bardliao@realtek.com --- sound/soc/codecs/rt5645.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index f9edf09..b6d5b95 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -2396,7 +2396,8 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_OFF: snd_soc_write(codec, RT5645_DEPOP_M2, 0x1100); - snd_soc_write(codec, RT5645_GEN_CTRL1, 0x0128); + snd_soc_update_bits(codec, RT5645_GEN_CTRL1, + RT5645_DIG_GATE_CTRL, 0); snd_soc_update_bits(codec, RT5645_PWR_ANLG1, RT5645_PWR_VREF1 | RT5645_PWR_MB | RT5645_PWR_BG | RT5645_PWR_VREF2 |
This driver will set RT5645_DEPOP_MAN bit in headphone power up depop process. We need to restore it in headphone power down process. Otherwise, we will get headphone noise when push button function is enabled.
Signed-off-by: Bard Liao bardliao@realtek.com --- sound/soc/codecs/rt5645.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index b6d5b95..69528ae 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -1270,6 +1270,8 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on) snd_soc_update_bits(codec, RT5645_PWR_ANLG1, RT5645_PWR_HP_L | RT5645_PWR_HP_R | RT5645_PWR_HA, 0); + snd_soc_update_bits(codec, RT5645_DEPOP_M2, + RT5645_DEPOP_MASK, 0); } } }
On Fri, Mar 27, 2015 at 08:19:06PM +0800, Bard Liao wrote:
rt5650 and rt5645 use different register bits for format configuration. This patch modifies rt5645_hw_params and rt5645_set_dai_fmt to support both codecs.
Applied all, thanks.
I am think if we should use different codec driver for rt5645 and rt5650. In fact, they are different Die. What do you think?
Well, it depends on how big the differences are for software really. If they are mostly register compatible then it's just going to be a few differences and the same code will work for both with small bits of per device code. If there are too many differences then you end up with more code handling those differences than is shared and it becomes better to split the drivers. Right now this doesn't look too different but I don't know what other changes you might need.
participants (2)
-
Bard Liao
-
Mark Brown