Skip to contentSkip to conversation

ASoC: rt5677: Add TDM channel select function

PATCH In review Oder Chiou 4 participants 6 messages Oct 15, 2014 – Oct 16, 2014

Subsystems (3)
lore
Share & tools
lore

Oder Chiou

author maintainer
#0 lore raw

PATCH 1/2 ASoC: rt5677: Add TDM channel select function

Add TDM channel select function.

---
 sound/soc/codecs/rt5677.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/rt5677.h | 16 ++++++++--
 2 files changed, 89 insertions(+), 2 deletions(-)
sound/soc/codecs/rt5677.c +75 -0
index 9f07146..52cbb56 100644
@@ -795,6 +795,14 @@ static unsigned int bst_tlv[] = {
 	8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0),
 };
 
+static const char * const rt5677_adc_tdm_mode[] = {
+	"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_adc_tdm_mode_enum,
+	SND_SOC_NOPM, 0, rt5677_adc_tdm_mode);
+
 static int rt5677_dsp_vad_get(struct snd_kcontrol *kcontrol,
 		struct snd_ctl_elem_value *ucontrol)
 {
@@ -820,6 +828,68 @@ static int rt5677_dsp_vad_put(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
+static int rt5677_if1_adc_tdm_get(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	unsigned int value;
+
+	regmap_read(rt5677->regmap, RT5677_TDM1_CTRL2, &value);
+
+	ucontrol->value.integer.value[0] = value & RT5677_IF1_ADC_CTRL_MASK;
+
+	return 0;
+}
+
+static int rt5677_if1_adc_tdm_put(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+
+	unsigned int value = ucontrol->value.integer.value[0];
+
+	regmap_update_bits(rt5677->regmap, RT5677_TDM1_CTRL2,
+		RT5677_IF1_ADC_CTRL_MASK, value);
+
+	regmap_update_bits(rt5677->regmap, RT5677_TDM1_CTRL1,
+		RT5677_IF1_ADC_MODE_MASK, (!!value) << RT5677_IF1_ADC_MODE_SFT);
+
+	return 0;
+}
+
+static int rt5677_if2_adc_tdm_get(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+	unsigned int value;
+
+	regmap_read(rt5677->regmap, RT5677_TDM2_CTRL2, &value);
+
+	ucontrol->value.integer.value[0] = value & RT5677_IF2_ADC_CTRL_MASK;
+
+	return 0;
+}
+
+static int rt5677_if2_adc_tdm_put(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+
+	unsigned int value = ucontrol->value.integer.value[0];
+
+	regmap_update_bits(rt5677->regmap, RT5677_TDM2_CTRL2,
+		RT5677_IF2_ADC_CTRL_MASK, value);
+
+	regmap_update_bits(rt5677->regmap, RT5677_TDM2_CTRL1,
+		RT5677_IF2_ADC_MODE_MASK, (!!value) << RT5677_IF2_ADC_MODE_SFT);
+
+	return 0;
+}
+
 static const struct snd_kcontrol_new rt5677_snd_controls[] = {
 	/* OUTPUT Control */
 	SOC_SINGLE("OUT1 Playback Switch", RT5677_LOUT1,
@@ -894,6 +964,11 @@ static const struct snd_kcontrol_new rt5677_snd_controls[] = {
 
 	SOC_SINGLE_EXT("DSP VAD Switch", SND_SOC_NOPM, 0, 1, 0,
 		rt5677_dsp_vad_get, rt5677_dsp_vad_put),
+
+	SOC_ENUM_EXT("ADC1 TDM Channel Switch", rt5677_adc_tdm_mode_enum,
+		rt5677_if1_adc_tdm_get, rt5677_if1_adc_tdm_put),
+	SOC_ENUM_EXT("ADC2 TDM Channel Switch", rt5677_adc_tdm_mode_enum,
+		rt5677_if2_adc_tdm_get, rt5677_if2_adc_tdm_put),
 };
 
 /**
sound/soc/codecs/rt5677.h +14 -2
index 20efa4a..20223eb 100644
@@ -799,7 +799,11 @@
 #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
+
+/* 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 +812,14 @@
 #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
+
+/* MX40 TDM2 control 1 (0x40) */
+#define RT5677_IF2_ADC_MODE_MASK		(0x1 << 12)
+#define RT5677_IF2_ADC_MODE_SFT			12
 
-/* MX41 TDM2 control 1 (0x41) */
+/* 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 +828,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)
Signature · 1 line
1.8.1.1.439.g50a6b54
author maintainer
#1 lore raw

PATCH 2/2 ASoC: rt5677: Revise the typo

Revise the typo.

---
 sound/soc/codecs/rt5677-spi.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/rt5677-spi.h +2 -2
index 7528bfd..ec41b2b 100644
@@ -9,8 +9,8 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef __RT5671_SPI_H__
-#define __RT5671_SPI_H__
+#ifndef __RT5677_SPI_H__
+#define __RT5677_SPI_H__
 
 #define RT5677_SPI_BUF_LEN 240
 #define RT5677_SPI_CMD_BURST_WRITE 0x05
Signature · 1 line
1.8.1.1.439.g50a6b54
#2 lore raw
In reply to Oder Chiou

Hi

Quoted 28 lines · Oder Chiou

Add TDM channel select function.

---
 sound/soc/codecs/rt5677.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/rt5677.h | 16 ++++++++--
 2 files changed, 89 insertions(+), 2 deletions(-)
sound/soc/codecs/rt5677.c +8 -0
index 9f07146..52cbb56 100644
@@ -795,6 +795,14 @@ static unsigned int bst_tlv[] = {
        8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0),
 };
 
+static const char * const rt5677_adc_tdm_mode[] = {
+       "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_adc_tdm_mode_enum,
+       SND_SOC_NOPM, 0, rt5677_adc_tdm_mode);
+
 static int rt5677_dsp_vad_get(struct snd_kcontrol *kcontrol,
                struct snd_ctl_elem_value *ucontrol)
 {

sound/soc/codecs/rt5677.c static int rt5677_dsp_vad_put(struct snd_kcontrol *kcontrol, · line 834

Quoted 7 lines
sound/soc/codecs/rt5677.c +4 -0
@@ -820,6 +828,68 @@ static int rt5677_dsp_vad_put(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
+static int rt5677_if1_adc_tdm_get(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);

When I use this patch I get a kernel crash in the next line. I need to use snd_soc_kcontrol_codec() instead of snd_kcontrol_chip() then it works fine.

I tested the patch by backporting it to 3.14.

Quoted 122 lines
sound/soc/codecs/rt5677.c +63 -0
+       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       unsigned int value;
+
+       regmap_read(rt5677->regmap, RT5677_TDM1_CTRL2, &value);
+
+       ucontrol->value.integer.value[0] = value & RT5677_IF1_ADC_CTRL_MASK;
+
+       return 0;
+}
+
+static int rt5677_if1_adc_tdm_put(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+
+       unsigned int value = ucontrol->value.integer.value[0];
+
+       regmap_update_bits(rt5677->regmap, RT5677_TDM1_CTRL2,
+               RT5677_IF1_ADC_CTRL_MASK, value);
+
+       regmap_update_bits(rt5677->regmap, RT5677_TDM1_CTRL1,
+               RT5677_IF1_ADC_MODE_MASK, (!!value) << RT5677_IF1_ADC_MODE_SFT);
+
+       return 0;
+}
+
+static int rt5677_if2_adc_tdm_get(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       unsigned int value;
+
+       regmap_read(rt5677->regmap, RT5677_TDM2_CTRL2, &value);
+
+       ucontrol->value.integer.value[0] = value & RT5677_IF2_ADC_CTRL_MASK;
+
+       return 0;
+}
+
+static int rt5677_if2_adc_tdm_put(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+
+       unsigned int value = ucontrol->value.integer.value[0];
+
+       regmap_update_bits(rt5677->regmap, RT5677_TDM2_CTRL2,
+               RT5677_IF2_ADC_CTRL_MASK, value);
+
+       regmap_update_bits(rt5677->regmap, RT5677_TDM2_CTRL1,
+               RT5677_IF2_ADC_MODE_MASK, (!!value) << RT5677_IF2_ADC_MODE_SFT);
+
+       return 0;
+}
+
 static const struct snd_kcontrol_new rt5677_snd_controls[] = {
        /* OUTPUT Control */
        SOC_SINGLE("OUT1 Playback Switch", RT5677_LOUT1,
@@ -894,6 +964,11 @@ static const struct snd_kcontrol_new rt5677_snd_controls[] = {
 
        SOC_SINGLE_EXT("DSP VAD Switch", SND_SOC_NOPM, 0, 1, 0,
                rt5677_dsp_vad_get, rt5677_dsp_vad_put),
+
+       SOC_ENUM_EXT("ADC1 TDM Channel Switch", rt5677_adc_tdm_mode_enum,
+               rt5677_if1_adc_tdm_get, rt5677_if1_adc_tdm_put),
+       SOC_ENUM_EXT("ADC2 TDM Channel Switch", rt5677_adc_tdm_mode_enum,
+               rt5677_if2_adc_tdm_get, rt5677_if2_adc_tdm_put),
 };
 
 /**
sound/soc/codecs/rt5677.h +14 -3
index 20efa4a..20223eb 100644
@@ -799,7 +799,11 @@
 #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
+
+/* 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 +812,14 @@
 #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
+
+/* MX40 TDM2 control 1 (0x40) */
+#define RT5677_IF2_ADC_MODE_MASK               (0x1 << 12)
+#define RT5677_IF2_ADC_MODE_SFT                        12
 
-/* MX41 TDM2 control 1 (0x41) */
+/* 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 +828,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)
--

1.8.1.1.439.g50a6b54

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#3 lore raw
In reply to Oder Chiou
Quoted 1 line · Oder Chiou

Add TDM channel select function.

Can you explain in a bit more detail what this does exactly? Is this for channel to slot mapping?

Thanks,
- Lars

author maintainer
#4 lore raw

Re: [PATCH 1/2] ASoC: rt5677: Add TDM channelselectfunction

Quoted 8 lines

-----Original Message-----
From: Lars-Peter Clausen [mailto:[email protected]]
Sent: Thursday, October 16, 2014 8:19 PM
To: Oder Chiou; [email protected]; [email protected]
Cc: Bard Liao; [email protected]; Flove
Subject: Re: [alsa-devel] [PATCH 1/2] ASoC: rt5677: Add TDM channel selectfunction

Quoted 6 lines
Quoted 1 line · Oder Chiou

Add TDM channel select function.

Can you explain in a bit more detail what this does exactly? Is this for channel to slot mapping?

Yes, 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 setting to item "2/1/3/4" or "2/3/1/4".

maintainer
#5 lore raw

Re: [PATCH 1/2] ASoC: rt5677: Add TDM channelselectfunction

On Thu, Oct 16, 2014 at 01:52:53PM +0000, Oder Chiou wrote:

Please fix your word wrapping so your lines are less than 80 columns long - something like 72 is good to allow for quoting.

Quoted 3 lines

Yes, 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 setting to item "2/1/3/4" or "2/3/1/4".

This should be implemented in DAPM rather than with a regular control - we're routing audio from the AIF/DAC/ADC within the device.