ASoC: rt5677: Add TDM channel mapping function

It is for channel to slot mapping, and it is not only for 8 channels mapping,
but also in 2, 4 and 6 channels mapping. If we want to use the 2 channels in
the stereo2 adc path, we need to set the item "2/1/3/4" or "2/3/1/4".

It also adds for stereo channel swap. It can map the sterero channels "L/R"
to "R/L", "L/L" or R/R.

Signed-off-by: Oder Chiou <oder_chiou@realtek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Oder Chiou 2014-10-22 16:11:39 +08:00 committed by Mark Brown
parent e29bee098e
commit e6f6ebc1f8
2 changed files with 261 additions and 14 deletions

View File

@ -1834,6 +1834,93 @@ static SOC_ENUM_SINGLE_DECL(
static const struct snd_kcontrol_new rt5677_if4_adc_mux =
SOC_DAPM_ENUM("IF4 ADC Source", rt5677_if4_adc_enum);
/* TDM IF1/2 ADC Data Selection */ /* MX-3B MX-40 [7:6][5:4][3:2][1:0] */
static const char * const rt5677_if12_adc_swap_src[] = {
"L/R", "R/L", "L/L", "R/R"
};
static SOC_ENUM_SINGLE_DECL(
rt5677_if1_adc1_swap_enum, RT5677_TDM1_CTRL1,
RT5677_IF1_ADC1_SWAP_SFT, rt5677_if12_adc_swap_src);
static const struct snd_kcontrol_new rt5677_if1_adc1_swap_mux =
SOC_DAPM_ENUM("IF1 ADC1 Swap Source", rt5677_if1_adc1_swap_enum);
static SOC_ENUM_SINGLE_DECL(
rt5677_if1_adc2_swap_enum, RT5677_TDM1_CTRL1,
RT5677_IF1_ADC2_SWAP_SFT, rt5677_if12_adc_swap_src);
static const struct snd_kcontrol_new rt5677_if1_adc2_swap_mux =
SOC_DAPM_ENUM("IF1 ADC2 Swap Source", rt5677_if1_adc2_swap_enum);
static SOC_ENUM_SINGLE_DECL(
rt5677_if1_adc3_swap_enum, RT5677_TDM1_CTRL1,
RT5677_IF1_ADC3_SWAP_SFT, rt5677_if12_adc_swap_src);
static const struct snd_kcontrol_new rt5677_if1_adc3_swap_mux =
SOC_DAPM_ENUM("IF1 ADC3 Swap Source", rt5677_if1_adc3_swap_enum);
static SOC_ENUM_SINGLE_DECL(
rt5677_if1_adc4_swap_enum, RT5677_TDM1_CTRL1,
RT5677_IF1_ADC4_SWAP_SFT, rt5677_if12_adc_swap_src);
static const struct snd_kcontrol_new rt5677_if1_adc4_swap_mux =
SOC_DAPM_ENUM("IF1 ADC4 Swap Source", rt5677_if1_adc4_swap_enum);
static SOC_ENUM_SINGLE_DECL(
rt5677_if2_adc1_swap_enum, RT5677_TDM2_CTRL1,
RT5677_IF1_ADC2_SWAP_SFT, rt5677_if12_adc_swap_src);
static const struct snd_kcontrol_new rt5677_if2_adc1_swap_mux =
SOC_DAPM_ENUM("IF1 ADC2 Swap Source", rt5677_if2_adc1_swap_enum);
static SOC_ENUM_SINGLE_DECL(
rt5677_if2_adc2_swap_enum, RT5677_TDM2_CTRL1,
RT5677_IF2_ADC2_SWAP_SFT, rt5677_if12_adc_swap_src);
static const struct snd_kcontrol_new rt5677_if2_adc2_swap_mux =
SOC_DAPM_ENUM("IF2 ADC2 Swap Source", rt5677_if2_adc2_swap_enum);
static SOC_ENUM_SINGLE_DECL(
rt5677_if2_adc3_swap_enum, RT5677_TDM2_CTRL1,
RT5677_IF2_ADC3_SWAP_SFT, rt5677_if12_adc_swap_src);
static const struct snd_kcontrol_new rt5677_if2_adc3_swap_mux =
SOC_DAPM_ENUM("IF2 ADC3 Swap Source", rt5677_if2_adc3_swap_enum);
static SOC_ENUM_SINGLE_DECL(
rt5677_if2_adc4_swap_enum, RT5677_TDM2_CTRL1,
RT5677_IF2_ADC4_SWAP_SFT, rt5677_if12_adc_swap_src);
static const struct snd_kcontrol_new rt5677_if2_adc4_swap_mux =
SOC_DAPM_ENUM("IF2 ADC4 Swap Source", rt5677_if2_adc4_swap_enum);
/* TDM IF1 ADC Data Selection */ /* MX-3C [2:0] */
static const char * const rt5677_if1_adc_tdm_swap_src[] = {
"1/2/3/4", "2/1/3/4", "2/3/1/4", "4/1/2/3", "1/3/2/4", "1/4/2/3",
"3/1/2/4", "3/4/1/2"
};
static SOC_ENUM_SINGLE_DECL(
rt5677_if1_adc_tdm_swap_enum, RT5677_TDM1_CTRL2,
RT5677_IF1_ADC_CTRL_SFT, rt5677_if1_adc_tdm_swap_src);
static const struct snd_kcontrol_new rt5677_if1_adc_tdm_swap_mux =
SOC_DAPM_ENUM("IF1 ADC TDM Swap Source", rt5677_if1_adc_tdm_swap_enum);
/* TDM IF2 ADC Data Selection */ /* MX-41[2:0] */
static const char * const rt5677_if2_adc_tdm_swap_src[] = {
"1/2/3/4", "2/1/3/4", "3/1/2/4", "4/1/2/3", "1/3/2/4", "1/4/2/3",
"2/3/1/4", "3/4/1/2"
};
static SOC_ENUM_SINGLE_DECL(
rt5677_if2_adc_tdm_swap_enum, RT5677_TDM2_CTRL2,
RT5677_IF2_ADC_CTRL_SFT, rt5677_if2_adc_tdm_swap_src);
static const struct snd_kcontrol_new rt5677_if2_adc_tdm_swap_mux =
SOC_DAPM_ENUM("IF2 ADC TDM Swap Source", rt5677_if2_adc_tdm_swap_enum);
static int rt5677_bst1_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@ -1945,6 +2032,52 @@ static int rt5677_set_micbias1_event(struct snd_soc_dapm_widget *w,
return 0;
}
static int rt5677_if1_adc_tdm_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = w->codec;
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
unsigned int value;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
regmap_read(rt5677->regmap, RT5677_TDM1_CTRL2, &value);
if (value & RT5677_IF1_ADC_CTRL_MASK)
regmap_update_bits(rt5677->regmap, RT5677_TDM1_CTRL1,
RT5677_IF1_ADC_MODE_MASK,
RT5677_IF1_ADC_MODE_TDM);
break;
default:
return 0;
}
return 0;
}
static int rt5677_if2_adc_tdm_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = w->codec;
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
unsigned int value;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
regmap_read(rt5677->regmap, RT5677_TDM2_CTRL2, &value);
if (value & RT5677_IF2_ADC_CTRL_MASK)
regmap_update_bits(rt5677->regmap, RT5677_TDM2_CTRL1,
RT5677_IF2_ADC_MODE_MASK,
RT5677_IF2_ADC_MODE_TDM);
break;
default:
return 0;
}
return 0;
}
static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("PLL1", RT5677_PWR_ANLG2, RT5677_PWR_PLL1_BIT,
0, rt5677_set_pll1_event, SND_SOC_DAPM_POST_PMU),
@ -2104,10 +2237,8 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = {
SND_SOC_DAPM_PGA("Stereo4 ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("Sto2 ADC LR MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("Mono ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("IF1_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("IF1_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("IF1_ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("IF1_ADC4", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("IF2 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
/* DSP */
SND_SOC_DAPM_MUX("IB9 Mux", SND_SOC_NOPM, 0, 0,
@ -2230,6 +2361,17 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = {
&rt5677_if1_adc3_mux),
SND_SOC_DAPM_MUX("IF1 ADC4 Mux", SND_SOC_NOPM, 0, 0,
&rt5677_if1_adc4_mux),
SND_SOC_DAPM_MUX("IF1 ADC1 Swap Mux", SND_SOC_NOPM, 0, 0,
&rt5677_if1_adc1_swap_mux),
SND_SOC_DAPM_MUX("IF1 ADC2 Swap Mux", SND_SOC_NOPM, 0, 0,
&rt5677_if1_adc2_swap_mux),
SND_SOC_DAPM_MUX("IF1 ADC3 Swap Mux", SND_SOC_NOPM, 0, 0,
&rt5677_if1_adc3_swap_mux),
SND_SOC_DAPM_MUX("IF1 ADC4 Swap Mux", SND_SOC_NOPM, 0, 0,
&rt5677_if1_adc4_swap_mux),
SND_SOC_DAPM_MUX_E("IF1 ADC TDM Swap Mux", SND_SOC_NOPM, 0, 0,
&rt5677_if1_adc_tdm_swap_mux, rt5677_if1_adc_tdm_event,
SND_SOC_DAPM_PRE_PMU),
SND_SOC_DAPM_MUX("IF2 ADC1 Mux", SND_SOC_NOPM, 0, 0,
&rt5677_if2_adc1_mux),
SND_SOC_DAPM_MUX("IF2 ADC2 Mux", SND_SOC_NOPM, 0, 0,
@ -2238,6 +2380,17 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = {
&rt5677_if2_adc3_mux),
SND_SOC_DAPM_MUX("IF2 ADC4 Mux", SND_SOC_NOPM, 0, 0,
&rt5677_if2_adc4_mux),
SND_SOC_DAPM_MUX("IF2 ADC1 Swap Mux", SND_SOC_NOPM, 0, 0,
&rt5677_if2_adc1_swap_mux),
SND_SOC_DAPM_MUX("IF2 ADC2 Swap Mux", SND_SOC_NOPM, 0, 0,
&rt5677_if2_adc2_swap_mux),
SND_SOC_DAPM_MUX("IF2 ADC3 Swap Mux", SND_SOC_NOPM, 0, 0,
&rt5677_if2_adc3_swap_mux),
SND_SOC_DAPM_MUX("IF2 ADC4 Swap Mux", SND_SOC_NOPM, 0, 0,
&rt5677_if2_adc4_swap_mux),
SND_SOC_DAPM_MUX_E("IF2 ADC TDM Swap Mux", SND_SOC_NOPM, 0, 0,
&rt5677_if2_adc_tdm_swap_mux, rt5677_if2_adc_tdm_event,
SND_SOC_DAPM_PRE_PMU),
SND_SOC_DAPM_MUX("IF3 ADC Mux", SND_SOC_NOPM, 0, 0,
&rt5677_if3_adc_mux),
SND_SOC_DAPM_MUX("IF4 ADC Mux", SND_SOC_NOPM, 0, 0,
@ -2621,11 +2774,42 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = {
{ "IF1 ADC4 Mux", "OB67", "OB67" },
{ "IF1 ADC4 Mux", "OB01", "OB01 Bypass Mux" },
{ "IF1 ADC1 Swap Mux", "L/R", "IF1 ADC1 Mux" },
{ "IF1 ADC1 Swap Mux", "R/L", "IF1 ADC1 Mux" },
{ "IF1 ADC1 Swap Mux", "L/L", "IF1 ADC1 Mux" },
{ "IF1 ADC1 Swap Mux", "R/R", "IF1 ADC1 Mux" },
{ "IF1 ADC2 Swap Mux", "L/R", "IF1 ADC2 Mux" },
{ "IF1 ADC2 Swap Mux", "R/L", "IF1 ADC2 Mux" },
{ "IF1 ADC2 Swap Mux", "L/L", "IF1 ADC2 Mux" },
{ "IF1 ADC2 Swap Mux", "R/R", "IF1 ADC2 Mux" },
{ "IF1 ADC3 Swap Mux", "L/R", "IF1 ADC3 Mux" },
{ "IF1 ADC3 Swap Mux", "R/L", "IF1 ADC3 Mux" },
{ "IF1 ADC3 Swap Mux", "L/L", "IF1 ADC3 Mux" },
{ "IF1 ADC3 Swap Mux", "R/R", "IF1 ADC3 Mux" },
{ "IF1 ADC4 Swap Mux", "L/R", "IF1 ADC4 Mux" },
{ "IF1 ADC4 Swap Mux", "R/L", "IF1 ADC4 Mux" },
{ "IF1 ADC4 Swap Mux", "L/L", "IF1 ADC4 Mux" },
{ "IF1 ADC4 Swap Mux", "R/R", "IF1 ADC4 Mux" },
{ "IF1 ADC", NULL, "IF1 ADC1 Swap Mux" },
{ "IF1 ADC", NULL, "IF1 ADC2 Swap Mux" },
{ "IF1 ADC", NULL, "IF1 ADC3 Swap Mux" },
{ "IF1 ADC", NULL, "IF1 ADC4 Swap Mux" },
{ "IF1 ADC TDM Swap Mux", "1/2/3/4", "IF1 ADC" },
{ "IF1 ADC TDM Swap Mux", "2/1/3/4", "IF1 ADC" },
{ "IF1 ADC TDM Swap Mux", "2/3/1/4", "IF1 ADC" },
{ "IF1 ADC TDM Swap Mux", "4/1/2/3", "IF1 ADC" },
{ "IF1 ADC TDM Swap Mux", "1/3/2/4", "IF1 ADC" },
{ "IF1 ADC TDM Swap Mux", "1/4/2/3", "IF1 ADC" },
{ "IF1 ADC TDM Swap Mux", "3/1/2/4", "IF1 ADC" },
{ "IF1 ADC TDM Swap Mux", "3/4/1/2", "IF1 ADC" },
{ "AIF1TX", NULL, "I2S1" },
{ "AIF1TX", NULL, "IF1 ADC1 Mux" },
{ "AIF1TX", NULL, "IF1 ADC2 Mux" },
{ "AIF1TX", NULL, "IF1 ADC3 Mux" },
{ "AIF1TX", NULL, "IF1 ADC4 Mux" },
{ "AIF1TX", NULL, "IF1 ADC TDM Swap Mux" },
{ "IF2 ADC1 Mux", "STO1 ADC MIX", "Stereo1 ADC MIX" },
{ "IF2 ADC1 Mux", "OB01", "OB01 Bypass Mux" },
@ -2642,11 +2826,42 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = {
{ "IF2 ADC4 Mux", "OB67", "OB67" },
{ "IF2 ADC4 Mux", "OB01", "OB01 Bypass Mux" },
{ "IF2 ADC1 Swap Mux", "L/R", "IF2 ADC1 Mux" },
{ "IF2 ADC1 Swap Mux", "R/L", "IF2 ADC1 Mux" },
{ "IF2 ADC1 Swap Mux", "L/L", "IF2 ADC1 Mux" },
{ "IF2 ADC1 Swap Mux", "R/R", "IF2 ADC1 Mux" },
{ "IF2 ADC2 Swap Mux", "L/R", "IF2 ADC2 Mux" },
{ "IF2 ADC2 Swap Mux", "R/L", "IF2 ADC2 Mux" },
{ "IF2 ADC2 Swap Mux", "L/L", "IF2 ADC2 Mux" },
{ "IF2 ADC2 Swap Mux", "R/R", "IF2 ADC2 Mux" },
{ "IF2 ADC3 Swap Mux", "L/R", "IF2 ADC3 Mux" },
{ "IF2 ADC3 Swap Mux", "R/L", "IF2 ADC3 Mux" },
{ "IF2 ADC3 Swap Mux", "L/L", "IF2 ADC3 Mux" },
{ "IF2 ADC3 Swap Mux", "R/R", "IF2 ADC3 Mux" },
{ "IF2 ADC4 Swap Mux", "L/R", "IF2 ADC4 Mux" },
{ "IF2 ADC4 Swap Mux", "R/L", "IF2 ADC4 Mux" },
{ "IF2 ADC4 Swap Mux", "L/L", "IF2 ADC4 Mux" },
{ "IF2 ADC4 Swap Mux", "R/R", "IF2 ADC4 Mux" },
{ "IF2 ADC", NULL, "IF2 ADC1 Swap Mux" },
{ "IF2 ADC", NULL, "IF2 ADC2 Swap Mux" },
{ "IF2 ADC", NULL, "IF2 ADC3 Swap Mux" },
{ "IF2 ADC", NULL, "IF2 ADC4 Swap Mux" },
{ "IF2 ADC TDM Swap Mux", "1/2/3/4", "IF2 ADC" },
{ "IF2 ADC TDM Swap Mux", "2/1/3/4", "IF2 ADC" },
{ "IF2 ADC TDM Swap Mux", "3/1/2/4", "IF2 ADC" },
{ "IF2 ADC TDM Swap Mux", "4/1/2/3", "IF2 ADC" },
{ "IF2 ADC TDM Swap Mux", "1/3/2/4", "IF2 ADC" },
{ "IF2 ADC TDM Swap Mux", "1/4/2/3", "IF2 ADC" },
{ "IF2 ADC TDM Swap Mux", "2/3/1/4", "IF2 ADC" },
{ "IF2 ADC TDM Swap Mux", "3/4/1/2", "IF2 ADC" },
{ "AIF2TX", NULL, "I2S2" },
{ "AIF2TX", NULL, "IF2 ADC1 Mux" },
{ "AIF2TX", NULL, "IF2 ADC2 Mux" },
{ "AIF2TX", NULL, "IF2 ADC3 Mux" },
{ "AIF2TX", NULL, "IF2 ADC4 Mux" },
{ "AIF2TX", NULL, "IF2 ADC TDM Swap Mux" },
{ "IF3 ADC Mux", "STO1 ADC MIX", "Stereo1 ADC MIX" },
{ "IF3 ADC Mux", "STO2 ADC MIX", "Stereo2 ADC MIX" },

View File

@ -799,7 +799,21 @@
#define RT5677_PDM2_I2C_EXE (0x1 << 1)
#define RT5677_PDM2_I2C_BUSY (0x1 << 0)
/* MX3C TDM1 control 1 (0x3c) */
/* MX3B TDM1 control 1 (0x3b) */
#define RT5677_IF1_ADC_MODE_MASK (0x1 << 12)
#define RT5677_IF1_ADC_MODE_SFT 12
#define RT5677_IF1_ADC_MODE_I2S (0x0 << 12)
#define RT5677_IF1_ADC_MODE_TDM (0x1 << 12)
#define RT5677_IF1_ADC1_SWAP_MASK (0x3 << 6)
#define RT5677_IF1_ADC1_SWAP_SFT 6
#define RT5677_IF1_ADC2_SWAP_MASK (0x3 << 4)
#define RT5677_IF1_ADC2_SWAP_SFT 4
#define RT5677_IF1_ADC3_SWAP_MASK (0x3 << 2)
#define RT5677_IF1_ADC3_SWAP_SFT 2
#define RT5677_IF1_ADC4_SWAP_MASK (0x3 << 0)
#define RT5677_IF1_ADC4_SWAP_SFT 0
/* MX3C TDM1 control 2 (0x3c) */
#define RT5677_IF1_ADC4_MASK (0x3 << 10)
#define RT5677_IF1_ADC4_SFT 10
#define RT5677_IF1_ADC3_MASK (0x3 << 8)
@ -808,8 +822,24 @@
#define RT5677_IF1_ADC2_SFT 6
#define RT5677_IF1_ADC1_MASK (0x3 << 4)
#define RT5677_IF1_ADC1_SFT 4
#define RT5677_IF1_ADC_CTRL_MASK (0x7 << 0)
#define RT5677_IF1_ADC_CTRL_SFT 0
/* MX41 TDM2 control 1 (0x41) */
/* MX40 TDM2 control 1 (0x40) */
#define RT5677_IF2_ADC_MODE_MASK (0x1 << 12)
#define RT5677_IF2_ADC_MODE_SFT 12
#define RT5677_IF2_ADC_MODE_I2S (0x0 << 12)
#define RT5677_IF2_ADC_MODE_TDM (0x1 << 12)
#define RT5677_IF2_ADC1_SWAP_MASK (0x3 << 6)
#define RT5677_IF2_ADC1_SWAP_SFT 6
#define RT5677_IF2_ADC2_SWAP_MASK (0x3 << 4)
#define RT5677_IF2_ADC2_SWAP_SFT 4
#define RT5677_IF2_ADC3_SWAP_MASK (0x3 << 2)
#define RT5677_IF2_ADC3_SWAP_SFT 2
#define RT5677_IF2_ADC4_SWAP_MASK (0x3 << 0)
#define RT5677_IF2_ADC4_SWAP_SFT 0
/* MX41 TDM2 control 2 (0x41) */
#define RT5677_IF2_ADC4_MASK (0x3 << 10)
#define RT5677_IF2_ADC4_SFT 10
#define RT5677_IF2_ADC3_MASK (0x3 << 8)
@ -818,6 +848,8 @@
#define RT5677_IF2_ADC2_SFT 6
#define RT5677_IF2_ADC1_MASK (0x3 << 4)
#define RT5677_IF2_ADC1_SFT 4
#define RT5677_IF2_ADC_CTRL_MASK (0x7 << 0)
#define RT5677_IF2_ADC_CTRL_SFT 0
/* Digital Microphone Control 1 (0x50) */
#define RT5677_DMIC_1_EN_MASK (0x1 << 15)