Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1472233 > unrolled thread

[PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.

Started byDanny Milosavljevic <dannym@scratchpost.org>
First post2016-08-30 07:50 +0200
Last post2016-09-01 15:30 +0200
Articles 10 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In. Danny Milosavljevic <dannym@scratchpost.org> - 2016-08-30 07:50 +0200
    Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture  Source, Differential Line-In. Chen-Yu Tsai <wens@csie.org> - 2016-08-31 08:30 +0200
      Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2,  Capture Source, Differential Line-In. Danny Milosavljevic <dannym@scratchpost.org> - 2016-08-31 09:20 +0200
        Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture  Source, Differential Line-In. Chen-Yu Tsai <wens@csie.org> - 2016-08-31 09:50 +0200
      Re: [linux-sunxi] Re: [PATCH v9 2/2] Add mixer controls: Line-In,  FM-In, Mic 2, Capture Source, Differential Line-In. Chen-Yu Tsai <wens@csie.org> - 2016-08-31 09:50 +0200
        Re: [linux-sunxi] Re: [PATCH v9 2/2] Add mixer controls: Line-In,  FM-In, Mic 2, Capture Source, Differential Line-In. Chen-Yu Tsai <wens@csie.org> - 2016-08-31 10:00 +0200
        Re: [linux-sunxi] Re: [PATCH v9 2/2] Add mixer controls: Line-In,  FM-In, Mic 2, Capture Source, Differential Line-In. Danny Milosavljevic <dannym@scratchpost.org> - 2016-08-31 10:00 +0200
      Re: [linux-sunxi] Re: [PATCH v9 2/2] Add mixer controls: Line-In,  FM-In, Mic 2, Capture Source, Differential Line-In. Danny Milosavljevic <dannym@scratchpost.org> - 2016-08-31 09:50 +0200
      Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2,  Capture Source, Differential Line-In. Danny Milosavljevic <dannym@scratchpost.org> - 2016-09-01 13:00 +0200
        Re: [linux-sunxi] Re: [PATCH v9 2/2] Add mixer controls: Line-In,  FM-In, Mic 2, Capture Source, Differential Line-In. Chen-Yu Tsai <wens@csie.org> - 2016-09-01 15:30 +0200

#1472233 — [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.

FromDanny Milosavljevic <dannym@scratchpost.org>
Date2016-08-30 07:50 +0200
Subject[PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.
Message-ID<sbK5P-Fr-1@gated-at.bofh.it>
Note: Mic1 Capture Volume is in a different register on A20 than on A10.
Note: Mic2 Capture Volume is in a different register on A20 than on A10.
---
 sound/soc/sunxi/sun4i-codec.c | 256 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 236 insertions(+), 20 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index 30f4ea2..f510e6d 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -59,9 +59,20 @@
 #define SUN4I_CODEC_DAC_ACTL_DACAENR			(31)
 #define SUN4I_CODEC_DAC_ACTL_DACAENL			(30)
 #define SUN4I_CODEC_DAC_ACTL_MIXEN			(29)
+#define SUN4I_CODEC_DAC_ACTL_LNG			(26)
+#define SUN4I_CODEC_DAC_ACTL_FMG			(23)
+#define SUN4I_CODEC_DAC_ACTL_MICG			(20)
+#define SUN4I_CODEC_DAC_ACTL_LLNS			(19)
+#define SUN4I_CODEC_DAC_ACTL_RLNS			(18)
+#define SUN4I_CODEC_DAC_ACTL_LFMS			(17)
+#define SUN4I_CODEC_DAC_ACTL_RFMS			(16)
 #define SUN4I_CODEC_DAC_ACTL_LDACLMIXS			(15)
 #define SUN4I_CODEC_DAC_ACTL_RDACRMIXS			(14)
 #define SUN4I_CODEC_DAC_ACTL_LDACRMIXS			(13)
+#define SUN4I_CODEC_DAC_ACTL_MIC1LS			(12)
+#define SUN4I_CODEC_DAC_ACTL_MIC1RS			(11)
+#define SUN4I_CODEC_DAC_ACTL_MIC2LS			(10)
+#define SUN4I_CODEC_DAC_ACTL_MIC2RS			(9)
 #define SUN4I_CODEC_DAC_ACTL_DACPAS			(8)
 #define SUN4I_CODEC_DAC_ACTL_MIXPAS			(7)
 #define SUN4I_CODEC_DAC_ACTL_PA_MUTE			(6)
@@ -87,8 +98,12 @@
 #define SUN4I_CODEC_ADC_ACTL_PREG1EN			(29)
 #define SUN4I_CODEC_ADC_ACTL_PREG2EN			(28)
 #define SUN4I_CODEC_ADC_ACTL_VMICEN			(27)
-#define SUN4I_CODEC_ADC_ACTL_VADCG			(20)
+#define SUN4I_CODEC_ADC_ACTL_PREG1			(25)
+#define SUN4I_CODEC_ADC_ACTL_PREG2			(23)
+#define SUN4I_CODEC_ADC_ACTL_ADCG			(20)
 #define SUN4I_CODEC_ADC_ACTL_ADCIS			(17)
+#define SUN4I_CODEC_ADC_ACTL_LNRDF			(16)
+#define SUN4I_CODEC_ADC_ACTL_LNPREG			(13)
 #define SUN4I_CODEC_ADC_ACTL_PA_EN			(4)
 #define SUN4I_CODEC_ADC_ACTL_DDE			(3)
 #define SUN4I_CODEC_ADC_DEBUG			(0x2c)
@@ -100,6 +115,9 @@
 #define SUN7I_CODEC_AC_DAC_CAL			(0x38)
 #define SUN7I_CODEC_AC_MIC_PHONE_CAL		(0x3c)
 
+#define SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG1      (29)
+#define SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG2      (26)
+
 struct sun4i_codec {
 	struct device	*dev;
 	struct regmap	*regmap;
@@ -509,23 +527,142 @@ static const struct snd_kcontrol_new sun4i_codec_pa_mute =
 			SUN4I_CODEC_DAC_ACTL_PA_MUTE, 1, 0);
 
 static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1);
+static DECLARE_TLV_DB_SCALE(sun4i_codec_linein_loopback_gain_scale,
+			    -150,
+			    150,
+			    0);
+static DECLARE_TLV_DB_SCALE(sun4i_codec_linein_preamp_gain_scale,
+			    -1200,
+			    300,
+			    0);
+static DECLARE_TLV_DB_SCALE(sun4i_codec_fmin_loopback_gain_scale,
+			    -450,
+			    150,
+			    0);
+static DECLARE_TLV_DB_SCALE(sun4i_codec_micin_loopback_gain_scale,
+			    -450,
+			    150,
+			    0);
+static DECLARE_TLV_DB_RANGE(sun4i_codec_micin_preamp_gain_scale,
+			    0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
+			    1, 7, TLV_DB_SCALE_ITEM(3500, 300, 0));
+static DECLARE_TLV_DB_SCALE(sun4i_codec_adc_gain_scale, -450, 150, 0);
+static DECLARE_TLV_DB_RANGE(sun7i_codec_micin_preamp_gain_scale,
+	0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
+	1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0)
+);
+
+static const char * const sun4i_codec_capture_source[] = {
+	"Line",
+	"FM",
+	"Mic1",
+	"Mic2",
+	"Mic1,Mic2",
+	"Mic1+Mic2",
+	"Output Mixer",
+	"Line,Mic1",
+};
+static SOC_ENUM_SINGLE_DECL(sun4i_codec_enum_capture_source,
+			    SUN4I_CODEC_ADC_ACTL,
+			    SUN4I_CODEC_ADC_ACTL_ADCIS,
+			    sun4i_codec_capture_source);
+
+static const struct snd_kcontrol_new sun4i_codec_capture_source_controls =
+	SOC_DAPM_ENUM("Capture Source", sun4i_codec_enum_capture_source);
+
+static const char * const sun4i_codec_difflinein_capture_source[] = {
+	"Non-Differential",
+	"Differential",
+};
+static SOC_ENUM_SINGLE_DECL(sun4i_codec_enum_difflinein_capture_source,
+			    SUN4I_CODEC_ADC_ACTL,
+			    SUN4I_CODEC_ADC_ACTL_ADCIS,
+			    sun4i_codec_difflinein_capture_source);
+
+static const struct snd_kcontrol_new sun4i_codec_difflinein_capture_source_controls =
+	SOC_DAPM_ENUM("Differential Line Capture Switch",
+	sun4i_codec_enum_difflinein_capture_source);
 
 #define SUN4I_COMMON_CODEC_CONTROLS \
-	SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL,\
-		       SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0,\
-		       sun4i_codec_pa_volume_scale)
+	SOC_SINGLE_TLV("Headphone Playback Volume", SUN4I_CODEC_DAC_ACTL,\
+		       SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0, \
+		       sun4i_codec_pa_volume_scale), \
+	/* Line, FM, Mic1, Mic2 */ \
+	SOC_SINGLE_TLV("Line Playback Volume", \
+		       SUN4I_CODEC_DAC_ACTL, \
+		       SUN4I_CODEC_DAC_ACTL_LNG, \
+		       1, \
+		       0, \
+		       sun4i_codec_linein_loopback_gain_scale), \
+	SOC_SINGLE_TLV("FM Playback Volume", \
+		       SUN4I_CODEC_DAC_ACTL, \
+		       SUN4I_CODEC_DAC_ACTL_FMG, \
+		       3, \
+		       0, \
+		       sun4i_codec_fmin_loopback_gain_scale), \
+	SOC_SINGLE_TLV("Mic Playback Volume", \
+		       SUN4I_CODEC_DAC_ACTL, \
+		       SUN4I_CODEC_DAC_ACTL_MICG, \
+		       7, \
+		       0, \
+		       sun4i_codec_micin_loopback_gain_scale), \
+	/* ADC */ \
+	SOC_SINGLE_TLV("Capture Volume", \
+		       SUN4I_CODEC_ADC_ACTL, \
+		       SUN4I_CODEC_ADC_ACTL_ADCG, \
+		       4, \
+		       0, \
+		       sun4i_codec_adc_gain_scale), \
+	SOC_SINGLE_TLV("Line Capture Volume", \
+		       SUN4I_CODEC_ADC_ACTL, \
+		       SUN4I_CODEC_ADC_ACTL_LNPREG, \
+		       7, \
+		       0, \
+		       sun4i_codec_linein_preamp_gain_scale)
 
 static const struct snd_kcontrol_new sun4i_codec_controls[] = {
 	SUN4I_COMMON_CODEC_CONTROLS,
+	SOC_SINGLE_TLV("Mic1 Capture Volume",
+		       SUN4I_CODEC_ADC_ACTL,
+		       SUN4I_CODEC_ADC_ACTL_PREG1,
+		       3,
+		       0,
+		       sun4i_codec_micin_preamp_gain_scale),
+	SOC_SINGLE_TLV("Mic2 Capture Volume",
+		       SUN4I_CODEC_ADC_ACTL,
+		       SUN4I_CODEC_ADC_ACTL_PREG2,
+		       3,
+		       0,
+		       sun4i_codec_micin_preamp_gain_scale),
 };
 
 static const struct snd_kcontrol_new sun7i_codec_controls[] = {
 	SUN4I_COMMON_CODEC_CONTROLS,
+	SOC_SINGLE_TLV("Mic1 Capture Volume",
+		       SUN7I_CODEC_AC_MIC_PHONE_CAL,
+		       SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG1,
+		       7,
+		       0,
+		       sun7i_codec_micin_preamp_gain_scale),
+	SOC_SINGLE_TLV("Mic2 Capture Volume",
+		       SUN7I_CODEC_AC_MIC_PHONE_CAL,
+		       SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG2,
+		       7,
+		       0,
+		       sun7i_codec_micin_preamp_gain_scale),
 };
 
 static const struct snd_kcontrol_new sun4i_codec_left_mixer_controls[] = {
 	SOC_DAPM_SINGLE("Left DAC Playback Switch", SUN4I_CODEC_DAC_ACTL,
 			SUN4I_CODEC_DAC_ACTL_LDACLMIXS, 1, 0),
+	SOC_DAPM_SINGLE("Left Line Playback Switch", SUN4I_CODEC_DAC_ACTL,
+			SUN4I_CODEC_DAC_ACTL_LLNS, 1, 0),
+	SOC_DAPM_SINGLE("Left FM Playback Switch", SUN4I_CODEC_DAC_ACTL,
+			SUN4I_CODEC_DAC_ACTL_LFMS, 1, 0),
+	SOC_DAPM_SINGLE("Mic1 Playback Switch", SUN4I_CODEC_DAC_ACTL,
+			SUN4I_CODEC_DAC_ACTL_MIC1LS, 1, 0),
+	SOC_DAPM_SINGLE("Mic2 Playback Switch", SUN4I_CODEC_DAC_ACTL,
+			SUN4I_CODEC_DAC_ACTL_MIC2LS, 1, 0),
 };
 
 static const struct snd_kcontrol_new sun4i_codec_right_mixer_controls[] = {
@@ -533,6 +670,14 @@ static const struct snd_kcontrol_new sun4i_codec_right_mixer_controls[] = {
 			SUN4I_CODEC_DAC_ACTL_RDACRMIXS, 1, 0),
 	SOC_DAPM_SINGLE("Left DAC Playback Switch", SUN4I_CODEC_DAC_ACTL,
 			SUN4I_CODEC_DAC_ACTL_LDACRMIXS, 1, 0),
+	SOC_DAPM_SINGLE("Right Line Playback Switch", SUN4I_CODEC_DAC_ACTL,
+			SUN4I_CODEC_DAC_ACTL_RLNS, 1, 0),
+	SOC_DAPM_SINGLE("Right FM Playback Switch", SUN4I_CODEC_DAC_ACTL,
+			SUN4I_CODEC_DAC_ACTL_RFMS, 1, 0),
+	SOC_DAPM_SINGLE("Mic1 Playback Switch", SUN4I_CODEC_DAC_ACTL,
+			SUN4I_CODEC_DAC_ACTL_MIC1RS, 1, 0),
+	SOC_DAPM_SINGLE("Mic2 Playback Switch", SUN4I_CODEC_DAC_ACTL,
+			SUN4I_CODEC_DAC_ACTL_MIC2RS, 1, 0),
 };
 
 static const struct snd_kcontrol_new sun4i_codec_pa_mixer_controls[] = {
@@ -565,6 +710,16 @@ static const struct snd_soc_dapm_widget sun4i_codec_codec_dapm_widgets[] = {
 	SND_SOC_DAPM_DAC("Right DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
 			 SUN4I_CODEC_DAC_ACTL_DACAENR, 0),
 
+	/* MUX */
+	SND_SOC_DAPM_MUX("Left Capture Select", SND_SOC_NOPM, 0, 0,
+			 &sun4i_codec_capture_source_controls),
+	SND_SOC_DAPM_MUX("Right Capture Select", SND_SOC_NOPM, 0, 0,
+			 &sun4i_codec_capture_source_controls),
+	SND_SOC_DAPM_MUX("Differential Line Capture Switch", SND_SOC_NOPM,
+			 0,
+			 0,
+			 &sun4i_codec_difflinein_capture_source_controls),
+
 	/* Mixers */
 	SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
 			   sun4i_codec_left_mixer_controls,
@@ -584,6 +739,8 @@ static const struct snd_soc_dapm_widget sun4i_codec_codec_dapm_widgets[] = {
 	/* Mic Pre-Amplifiers */
 	SND_SOC_DAPM_PGA("MIC1 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
 			 SUN4I_CODEC_ADC_ACTL_PREG1EN, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("MIC2 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
+			 SUN4I_CODEC_ADC_ACTL_PREG2EN, 0, NULL, 0),
 
 	/* Power Amplifier */
 	SND_SOC_DAPM_MIXER("Power Amplifier", SUN4I_CODEC_ADC_ACTL,
@@ -593,8 +750,15 @@ static const struct snd_soc_dapm_widget sun4i_codec_codec_dapm_widgets[] = {
 	SND_SOC_DAPM_SWITCH("Power Amplifier Mute", SND_SOC_NOPM, 0, 0,
 			    &sun4i_codec_pa_mute),
 
+	/* Inputs */
 	SND_SOC_DAPM_INPUT("Mic1"),
+	SND_SOC_DAPM_INPUT("Mic2"),
+	SND_SOC_DAPM_INPUT("Line Right"),
+	SND_SOC_DAPM_INPUT("Line Left"),
+	SND_SOC_DAPM_INPUT("FM Right"),
+	SND_SOC_DAPM_INPUT("FM Left"),
 
+	/* Outputs */
 	SND_SOC_DAPM_OUTPUT("HP Right"),
 	SND_SOC_DAPM_OUTPUT("HP Left"),
 };
@@ -608,14 +772,22 @@ static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = {
 	{ "Right ADC", NULL, "ADC" },
 	{ "Right DAC", NULL, "DAC" },
 
+	/* Left Mixer Routes */
+	{ "Left Mixer", NULL, "Mixer Enable" },
+	{ "Left Mixer", "Left DAC Playback Switch", "Left DAC" },
+	{ "Left Mixer", "Mic1 Playback Switch", "MIC1 Pre-Amplifier" },
+	{ "Left Mixer", "Mic2 Playback Switch", "MIC2 Pre-Amplifier" },
+	{ "Left Mixer", "Left Line Playback Switch", "Line Left" },
+	{ "Left Mixer", "Left FM Playback Switch", "FM Left" },
+
 	/* Right Mixer Routes */
 	{ "Right Mixer", NULL, "Mixer Enable" },
 	{ "Right Mixer", "Left DAC Playback Switch", "Left DAC" },
 	{ "Right Mixer", "Right DAC Playback Switch", "Right DAC" },
-
-	/* Left Mixer Routes */
-	{ "Left Mixer", NULL, "Mixer Enable" },
-	{ "Left Mixer", "Left DAC Playback Switch", "Left DAC" },
+	{ "Right Mixer", "Mic1 Playback Switch", "MIC1 Pre-Amplifier" },
+	{ "Right Mixer", "Mic2 Playback Switch", "MIC2 Pre-Amplifier" },
+	{ "Right Mixer", "Right Line Playback Switch", "Line Right" },
+	{ "Right Mixer", "Right FM Playback Switch", "FM Right" },
 
 	/* Power Amplifier Routes */
 	{ "Power Amplifier", "Mixer Playback Switch", "Left Mixer" },
@@ -633,26 +805,70 @@ static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = {
 	{ "Right ADC", NULL, "MIC1 Pre-Amplifier" },
 	{ "MIC1 Pre-Amplifier", NULL, "Mic1"},
 	{ "Mic1", NULL, "VMIC" },
+	/* see also Left Mixer Routes, Right Mixer Routes */
+
+	/* Mic2 Routes */
+	{ "Left ADC", NULL, "MIC2 Pre-Amplifier" },
+	{ "Right ADC", NULL, "MIC2 Pre-Amplifier" },
+	{ "MIC2 Pre-Amplifier", NULL, "Mic2"},
+	{ "Mic2", NULL, "VMIC" },
+	/* see also Left Mixer Routes, Right Mixer Routes */
+
+	/* Line, FM Routes */
+	/* see also Left Mixer Routes, Right Mixer Routes */
+
+	/* LNRDF Routes */
+	{ "Differential Line Capture Switch", "Differential", "Line Left" },
+	{ "Differential Line Capture Switch", "Differential", "Line Right" },
+	/*{ "Differential Line Capture Switch", "Non-Differential", "Line X" }, implicit */
+
+	/* Left ADC Input Routes */
+	{ "Left Capture Select", "Line", "Line Left" },
+	{ "Left Capture Select", "Line", "Differential Line Capture Switch" },
+	{ "Left Capture Select", "FM", "FM Left" },
+	{ "Left Capture Select", "Mic1", "MIC1 Pre-Amplifier" },
+	{ "Left Capture Select", "Mic2", "MIC2 Pre-Amplifier" },
+	{ "Left Capture Select", "Mic1,Mic2", "MIC1 Pre-Amplifier" },
+	{ "Left Capture Select", "Mic1+Mic2", "MIC1 Pre-Amplifier" },
+	{ "Left Capture Select", "Mic1+Mic2", "MIC2 Pre-Amplifier" },
+	{ "Left Capture Select", "Output Mixer", "Left Mixer" },
+	{ "Left Capture Select", "Line,Mic1", "Line Left" },
+	{ "Left Capture Select", "Line,Mic1", "Differential Line Capture Switch" },
+	{ "Left ADC", NULL, "Left Capture Select" },
+
+	/* Right ADC Input Routes */
+	{ "Right Capture Select", "Line", "Line Right" },
+	{ "Right Capture Select", "Line", "Differential Line Capture Switch" },
+	{ "Right Capture Select", "FM", "FM Right" },
+	{ "Right Capture Select", "Mic1", "MIC1 Pre-Amplifier" },
+	{ "Right Capture Select", "Mic2", "MIC2 Pre-Amplifier" },
+	{ "Right Capture Select", "Mic1,Mic2", "MIC2 Pre-Amplifier" },
+	{ "Right Capture Select", "Mic1+Mic2", "MIC2 Pre-Amplifier" },
+	{ "Right Capture Select", "Mic1+Mic2", "MIC1 Pre-Amplifier" },
+	{ "Right Capture Select", "Output Mixer", "Right Mixer" },
+	{ "Right Capture Select", "Line,Mic1", "MIC1 Pre-Amplifier" },
+	{ "Right ADC", NULL, "Right Capture Select" },
 };
 
 static struct snd_soc_codec_driver sun4i_codec_codec = {
 	.component_driver = {
-		.controls		= sun4i_codec_controls,
-		.num_controls		= ARRAY_SIZE(sun4i_codec_controls),
-		.dapm_widgets           = sun4i_codec_codec_dapm_widgets,
-		.num_dapm_widgets       = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
-		.dapm_routes            = sun4i_codec_codec_dapm_routes,
-		.num_dapm_routes        = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
+		.controls         = sun4i_codec_controls,
+		.num_controls     = ARRAY_SIZE(sun4i_codec_controls),
+		.dapm_widgets     = sun4i_codec_codec_dapm_widgets,
+		.num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
+		.dapm_routes      = sun4i_codec_codec_dapm_routes,
+		.num_dapm_routes  = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
 	},
 };
+
 static struct snd_soc_codec_driver sun7i_codec_codec = {
 	.component_driver = {
-		.controls               = sun7i_codec_controls,
-		.num_controls           = ARRAY_SIZE(sun7i_codec_controls),
-		.dapm_widgets		= sun4i_codec_codec_dapm_widgets,
-		.num_dapm_widgets	= ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
-		.dapm_routes		= sun4i_codec_codec_dapm_routes,
-		.num_dapm_routes	= ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
+		.controls         = sun7i_codec_controls,
+		.num_controls     = ARRAY_SIZE(sun7i_codec_controls),
+		.dapm_widgets     = sun4i_codec_codec_dapm_widgets,
+		.num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
+		.dapm_routes      = sun4i_codec_codec_dapm_routes,
+		.num_dapm_routes  = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
 	},
 };
 

[toc] | [next] | [standalone]


#1473058 — Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.

FromChen-Yu Tsai <wens@csie.org>
Date2016-08-31 08:30 +0200
SubjectRe: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.
Message-ID<sc7c5-7gk-7@gated-at.bofh.it>
In reply to#1472233
Hi,

On Tue, Aug 30, 2016 at 1:44 PM, Danny Milosavljevic
<dannym@scratchpost.org> wrote:
> Note: Mic1 Capture Volume is in a different register on A20 than on A10.
> Note: Mic2 Capture Volume is in a different register on A20 than on A10.

The subject would be better saying "Add support for Line-In, FM-In, Mic 2
and Capture Source paths". You are not just adding mixer controls, but
DAPM widgets and routes as well.


A general description and any quirks of the hardware would be nice,
such as the capture source has a mux and not a mixer, in addition to
what you mentioned.

> ---
>  sound/soc/sunxi/sun4i-codec.c | 256 ++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 236 insertions(+), 20 deletions(-)
>
> diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
> index 30f4ea2..f510e6d 100644
> --- a/sound/soc/sunxi/sun4i-codec.c
> +++ b/sound/soc/sunxi/sun4i-codec.c
> @@ -59,9 +59,20 @@
>  #define SUN4I_CODEC_DAC_ACTL_DACAENR                   (31)
>  #define SUN4I_CODEC_DAC_ACTL_DACAENL                   (30)
>  #define SUN4I_CODEC_DAC_ACTL_MIXEN                     (29)
> +#define SUN4I_CODEC_DAC_ACTL_LNG                       (26)
> +#define SUN4I_CODEC_DAC_ACTL_FMG                       (23)
> +#define SUN4I_CODEC_DAC_ACTL_MICG                      (20)
> +#define SUN4I_CODEC_DAC_ACTL_LLNS                      (19)
> +#define SUN4I_CODEC_DAC_ACTL_RLNS                      (18)
> +#define SUN4I_CODEC_DAC_ACTL_LFMS                      (17)
> +#define SUN4I_CODEC_DAC_ACTL_RFMS                      (16)
>  #define SUN4I_CODEC_DAC_ACTL_LDACLMIXS                 (15)
>  #define SUN4I_CODEC_DAC_ACTL_RDACRMIXS                 (14)
>  #define SUN4I_CODEC_DAC_ACTL_LDACRMIXS                 (13)
> +#define SUN4I_CODEC_DAC_ACTL_MIC1LS                    (12)
> +#define SUN4I_CODEC_DAC_ACTL_MIC1RS                    (11)
> +#define SUN4I_CODEC_DAC_ACTL_MIC2LS                    (10)
> +#define SUN4I_CODEC_DAC_ACTL_MIC2RS                    (9)
>  #define SUN4I_CODEC_DAC_ACTL_DACPAS                    (8)
>  #define SUN4I_CODEC_DAC_ACTL_MIXPAS                    (7)
>  #define SUN4I_CODEC_DAC_ACTL_PA_MUTE                   (6)
> @@ -87,8 +98,12 @@
>  #define SUN4I_CODEC_ADC_ACTL_PREG1EN                   (29)
>  #define SUN4I_CODEC_ADC_ACTL_PREG2EN                   (28)
>  #define SUN4I_CODEC_ADC_ACTL_VMICEN                    (27)
> -#define SUN4I_CODEC_ADC_ACTL_VADCG                     (20)
> +#define SUN4I_CODEC_ADC_ACTL_PREG1                     (25)
> +#define SUN4I_CODEC_ADC_ACTL_PREG2                     (23)
> +#define SUN4I_CODEC_ADC_ACTL_ADCG                      (20)
>  #define SUN4I_CODEC_ADC_ACTL_ADCIS                     (17)
> +#define SUN4I_CODEC_ADC_ACTL_LNRDF                     (16)
> +#define SUN4I_CODEC_ADC_ACTL_LNPREG                    (13)
>  #define SUN4I_CODEC_ADC_ACTL_PA_EN                     (4)
>  #define SUN4I_CODEC_ADC_ACTL_DDE                       (3)
>  #define SUN4I_CODEC_ADC_DEBUG                  (0x2c)
> @@ -100,6 +115,9 @@
>  #define SUN7I_CODEC_AC_DAC_CAL                 (0x38)
>  #define SUN7I_CODEC_AC_MIC_PHONE_CAL           (0x3c)
>
> +#define SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG1      (29)
> +#define SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG2      (26)
> +
>  struct sun4i_codec {
>         struct device   *dev;
>         struct regmap   *regmap;
> @@ -509,23 +527,142 @@ static const struct snd_kcontrol_new sun4i_codec_pa_mute =
>                         SUN4I_CODEC_DAC_ACTL_PA_MUTE, 1, 0);
>
>  static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1);
> +static DECLARE_TLV_DB_SCALE(sun4i_codec_linein_loopback_gain_scale,

X_playback_gain_scale, matching the control names later.

> +                           -150,
> +                           150,
> +                           0);
> +static DECLARE_TLV_DB_SCALE(sun4i_codec_linein_preamp_gain_scale,
> +                           -1200,
> +                           300,
> +                           0);
> +static DECLARE_TLV_DB_SCALE(sun4i_codec_fmin_loopback_gain_scale,
> +                           -450,
> +                           150,
> +                           0);
> +static DECLARE_TLV_DB_SCALE(sun4i_codec_micin_loopback_gain_scale,
> +                           -450,
> +                           150,
> +                           0);

Please merge the above 2. Also can they be const? Same for all the
other TLV structures.

> +static DECLARE_TLV_DB_RANGE(sun4i_codec_micin_preamp_gain_scale,
> +                           0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
> +                           1, 7, TLV_DB_SCALE_ITEM(3500, 300, 0));
> +static DECLARE_TLV_DB_SCALE(sun4i_codec_adc_gain_scale, -450, 150, 0);
> +static DECLARE_TLV_DB_RANGE(sun7i_codec_micin_preamp_gain_scale,
> +       0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
> +       1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0)
> +);
> +
> +static const char * const sun4i_codec_capture_source[] = {
> +       "Line",
> +       "FM",
> +       "Mic1",
> +       "Mic2",
> +       "Mic1,Mic2",
> +       "Mic1+Mic2",
> +       "Output Mixer",

Given there's only one mixer in the system, you can drop the "Output".

> +       "Line,Mic1",
> +};
> +static SOC_ENUM_SINGLE_DECL(sun4i_codec_enum_capture_source,
> +                           SUN4I_CODEC_ADC_ACTL,
> +                           SUN4I_CODEC_ADC_ACTL_ADCIS,
> +                           sun4i_codec_capture_source);
> +
> +static const struct snd_kcontrol_new sun4i_codec_capture_source_controls =
> +       SOC_DAPM_ENUM("Capture Source", sun4i_codec_enum_capture_source);
> +
> +static const char * const sun4i_codec_difflinein_capture_source[] = {
> +       "Non-Differential",
> +       "Differential",

How about "Stereo"? And possibly "Mono Differential"? or just "Mono".
A differential input can be used single-ended by grounding one side.

> +};
> +static SOC_ENUM_SINGLE_DECL(sun4i_codec_enum_difflinein_capture_source,
> +                           SUN4I_CODEC_ADC_ACTL,
> +                           SUN4I_CODEC_ADC_ACTL_ADCIS,
> +                           sun4i_codec_difflinein_capture_source);
> +
> +static const struct snd_kcontrol_new sun4i_codec_difflinein_capture_source_controls =
> +       SOC_DAPM_ENUM("Differential Line Capture Switch",
> +       sun4i_codec_enum_difflinein_capture_source);
>
>  #define SUN4I_COMMON_CODEC_CONTROLS \
> -       SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL,\
> -                      SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0,\
> -                      sun4i_codec_pa_volume_scale)
> +       SOC_SINGLE_TLV("Headphone Playback Volume", SUN4I_CODEC_DAC_ACTL,\
> +                      SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0, \
> +                      sun4i_codec_pa_volume_scale), \
> +       /* Line, FM, Mic1, Mic2 */ \
> +       SOC_SINGLE_TLV("Line Playback Volume", \
> +                      SUN4I_CODEC_DAC_ACTL, \
> +                      SUN4I_CODEC_DAC_ACTL_LNG, \
> +                      1, \
> +                      0, \
> +                      sun4i_codec_linein_loopback_gain_scale), \
> +       SOC_SINGLE_TLV("FM Playback Volume", \
> +                      SUN4I_CODEC_DAC_ACTL, \
> +                      SUN4I_CODEC_DAC_ACTL_FMG, \
> +                      3, \
> +                      0, \
> +                      sun4i_codec_fmin_loopback_gain_scale), \
> +       SOC_SINGLE_TLV("Mic Playback Volume", \
> +                      SUN4I_CODEC_DAC_ACTL, \
> +                      SUN4I_CODEC_DAC_ACTL_MICG, \
> +                      7, \
> +                      0, \
> +                      sun4i_codec_micin_loopback_gain_scale), \
> +       /* ADC */ \
> +       SOC_SINGLE_TLV("Capture Volume", \
> +                      SUN4I_CODEC_ADC_ACTL, \
> +                      SUN4I_CODEC_ADC_ACTL_ADCG, \
> +                      4, \
> +                      0, \
> +                      sun4i_codec_adc_gain_scale), \
> +       SOC_SINGLE_TLV("Line Capture Volume", \
> +                      SUN4I_CODEC_ADC_ACTL, \
> +                      SUN4I_CODEC_ADC_ACTL_LNPREG, \
> +                      7, \
> +                      0, \
> +                      sun4i_codec_linein_preamp_gain_scale)

Nope. This is a pre-gain or boost. It affects both playback and
capture. "Line Boost Volume" would be better.

>
>  static const struct snd_kcontrol_new sun4i_codec_controls[] = {
>         SUN4I_COMMON_CODEC_CONTROLS,
> +       SOC_SINGLE_TLV("Mic1 Capture Volume",
> +                      SUN4I_CODEC_ADC_ACTL,
> +                      SUN4I_CODEC_ADC_ACTL_PREG1,
> +                      3,
> +                      0,
> +                      sun4i_codec_micin_preamp_gain_scale),
> +       SOC_SINGLE_TLV("Mic2 Capture Volume",
> +                      SUN4I_CODEC_ADC_ACTL,
> +                      SUN4I_CODEC_ADC_ACTL_PREG2,
> +                      3,
> +                      0,
> +                      sun4i_codec_micin_preamp_gain_scale),
>  };
>
>  static const struct snd_kcontrol_new sun7i_codec_controls[] = {
>         SUN4I_COMMON_CODEC_CONTROLS,
> +       SOC_SINGLE_TLV("Mic1 Capture Volume",
> +                      SUN7I_CODEC_AC_MIC_PHONE_CAL,
> +                      SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG1,
> +                      7,
> +                      0,
> +                      sun7i_codec_micin_preamp_gain_scale),
> +       SOC_SINGLE_TLV("Mic2 Capture Volume",
> +                      SUN7I_CODEC_AC_MIC_PHONE_CAL,
> +                      SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG2,
> +                      7,
> +                      0,
> +                      sun7i_codec_micin_preamp_gain_scale),

Same for the Mic pre-amp gain controls.

>  };
>
>  static const struct snd_kcontrol_new sun4i_codec_left_mixer_controls[] = {
>         SOC_DAPM_SINGLE("Left DAC Playback Switch", SUN4I_CODEC_DAC_ACTL,
>                         SUN4I_CODEC_DAC_ACTL_LDACLMIXS, 1, 0),
> +       SOC_DAPM_SINGLE("Left Line Playback Switch", SUN4I_CODEC_DAC_ACTL,
> +                       SUN4I_CODEC_DAC_ACTL_LLNS, 1, 0),
> +       SOC_DAPM_SINGLE("Left FM Playback Switch", SUN4I_CODEC_DAC_ACTL,
> +                       SUN4I_CODEC_DAC_ACTL_LFMS, 1, 0),
> +       SOC_DAPM_SINGLE("Mic1 Playback Switch", SUN4I_CODEC_DAC_ACTL,
> +                       SUN4I_CODEC_DAC_ACTL_MIC1LS, 1, 0),
> +       SOC_DAPM_SINGLE("Mic2 Playback Switch", SUN4I_CODEC_DAC_ACTL,
> +                       SUN4I_CODEC_DAC_ACTL_MIC2LS, 1, 0),
>  };
>
>  static const struct snd_kcontrol_new sun4i_codec_right_mixer_controls[] = {
> @@ -533,6 +670,14 @@ static const struct snd_kcontrol_new sun4i_codec_right_mixer_controls[] = {
>                         SUN4I_CODEC_DAC_ACTL_RDACRMIXS, 1, 0),
>         SOC_DAPM_SINGLE("Left DAC Playback Switch", SUN4I_CODEC_DAC_ACTL,
>                         SUN4I_CODEC_DAC_ACTL_LDACRMIXS, 1, 0),
> +       SOC_DAPM_SINGLE("Right Line Playback Switch", SUN4I_CODEC_DAC_ACTL,
> +                       SUN4I_CODEC_DAC_ACTL_RLNS, 1, 0),
> +       SOC_DAPM_SINGLE("Right FM Playback Switch", SUN4I_CODEC_DAC_ACTL,
> +                       SUN4I_CODEC_DAC_ACTL_RFMS, 1, 0),
> +       SOC_DAPM_SINGLE("Mic1 Playback Switch", SUN4I_CODEC_DAC_ACTL,
> +                       SUN4I_CODEC_DAC_ACTL_MIC1RS, 1, 0),
> +       SOC_DAPM_SINGLE("Mic2 Playback Switch", SUN4I_CODEC_DAC_ACTL,
> +                       SUN4I_CODEC_DAC_ACTL_MIC2RS, 1, 0),

I have a few patches that introduce SOC_DAPM_DOUBLE, so you can share a
control between left/right channels. IMHO it makes the userspace mixer
less confusing.

>  };
>
>  static const struct snd_kcontrol_new sun4i_codec_pa_mixer_controls[] = {
> @@ -565,6 +710,16 @@ static const struct snd_soc_dapm_widget sun4i_codec_codec_dapm_widgets[] = {
>         SND_SOC_DAPM_DAC("Right DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
>                          SUN4I_CODEC_DAC_ACTL_DACAENR, 0),
>
> +       /* MUX */
> +       SND_SOC_DAPM_MUX("Left Capture Select", SND_SOC_NOPM, 0, 0,
> +                        &sun4i_codec_capture_source_controls),
> +       SND_SOC_DAPM_MUX("Right Capture Select", SND_SOC_NOPM, 0, 0,
> +                        &sun4i_codec_capture_source_controls),
> +       SND_SOC_DAPM_MUX("Differential Line Capture Switch", SND_SOC_NOPM,
> +                        0,
> +                        0,
> +                        &sun4i_codec_difflinein_capture_source_controls),

The proper function suffix is "Route", not "Select".

> +
>         /* Mixers */
>         SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
>                            sun4i_codec_left_mixer_controls,
> @@ -584,6 +739,8 @@ static const struct snd_soc_dapm_widget sun4i_codec_codec_dapm_widgets[] = {
>         /* Mic Pre-Amplifiers */
>         SND_SOC_DAPM_PGA("MIC1 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
>                          SUN4I_CODEC_ADC_ACTL_PREG1EN, 0, NULL, 0),
> +       SND_SOC_DAPM_PGA("MIC2 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
> +                        SUN4I_CODEC_ADC_ACTL_PREG2EN, 0, NULL, 0),
>
>         /* Power Amplifier */
>         SND_SOC_DAPM_MIXER("Power Amplifier", SUN4I_CODEC_ADC_ACTL,
> @@ -593,8 +750,15 @@ static const struct snd_soc_dapm_widget sun4i_codec_codec_dapm_widgets[] = {
>         SND_SOC_DAPM_SWITCH("Power Amplifier Mute", SND_SOC_NOPM, 0, 0,
>                             &sun4i_codec_pa_mute),
>
> +       /* Inputs */
>         SND_SOC_DAPM_INPUT("Mic1"),
> +       SND_SOC_DAPM_INPUT("Mic2"),

How about SND_SOC_DAPM_MIC? And what about microphone bias?

> +       SND_SOC_DAPM_INPUT("Line Right"),
> +       SND_SOC_DAPM_INPUT("Line Left"),
> +       SND_SOC_DAPM_INPUT("FM Right"),
> +       SND_SOC_DAPM_INPUT("FM Left"),

Why the left/right channels? You aren't doing anything special for
them. You could just have one Line and one FM, and have routes to
left/right mixers.

>
> +       /* Outputs */
>         SND_SOC_DAPM_OUTPUT("HP Right"),
>         SND_SOC_DAPM_OUTPUT("HP Left"),
>  };
> @@ -608,14 +772,22 @@ static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = {
>         { "Right ADC", NULL, "ADC" },
>         { "Right DAC", NULL, "DAC" },
>
> +       /* Left Mixer Routes */
> +       { "Left Mixer", NULL, "Mixer Enable" },
> +       { "Left Mixer", "Left DAC Playback Switch", "Left DAC" },
> +       { "Left Mixer", "Mic1 Playback Switch", "MIC1 Pre-Amplifier" },
> +       { "Left Mixer", "Mic2 Playback Switch", "MIC2 Pre-Amplifier" },
> +       { "Left Mixer", "Left Line Playback Switch", "Line Left" },
> +       { "Left Mixer", "Left FM Playback Switch", "FM Left" },
> +
>         /* Right Mixer Routes */
>         { "Right Mixer", NULL, "Mixer Enable" },
>         { "Right Mixer", "Left DAC Playback Switch", "Left DAC" },
>         { "Right Mixer", "Right DAC Playback Switch", "Right DAC" },
> -
> -       /* Left Mixer Routes */
> -       { "Left Mixer", NULL, "Mixer Enable" },
> -       { "Left Mixer", "Left DAC Playback Switch", "Left DAC" },
> +       { "Right Mixer", "Mic1 Playback Switch", "MIC1 Pre-Amplifier" },
> +       { "Right Mixer", "Mic2 Playback Switch", "MIC2 Pre-Amplifier" },
> +       { "Right Mixer", "Right Line Playback Switch", "Line Right" },
> +       { "Right Mixer", "Right FM Playback Switch", "FM Right" },
>
>         /* Power Amplifier Routes */
>         { "Power Amplifier", "Mixer Playback Switch", "Left Mixer" },
> @@ -633,26 +805,70 @@ static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = {
>         { "Right ADC", NULL, "MIC1 Pre-Amplifier" },
>         { "MIC1 Pre-Amplifier", NULL, "Mic1"},
>         { "Mic1", NULL, "VMIC" },
> +       /* see also Left Mixer Routes, Right Mixer Routes */
> +
> +       /* Mic2 Routes */
> +       { "Left ADC", NULL, "MIC2 Pre-Amplifier" },
> +       { "Right ADC", NULL, "MIC2 Pre-Amplifier" },
> +       { "MIC2 Pre-Amplifier", NULL, "Mic2"},
> +       { "Mic2", NULL, "VMIC" },
> +       /* see also Left Mixer Routes, Right Mixer Routes */
> +
> +       /* Line, FM Routes */
> +       /* see also Left Mixer Routes, Right Mixer Routes */
> +
> +       /* LNRDF Routes */
> +       { "Differential Line Capture Switch", "Differential", "Line Left" },
> +       { "Differential Line Capture Switch", "Differential", "Line Right" },
> +       /*{ "Differential Line Capture Switch", "Non-Differential", "Line X" }, implicit */
> +
> +       /* Left ADC Input Routes */
> +       { "Left Capture Select", "Line", "Line Left" },
> +       { "Left Capture Select", "Line", "Differential Line Capture Switch" },
> +       { "Left Capture Select", "FM", "FM Left" },
> +       { "Left Capture Select", "Mic1", "MIC1 Pre-Amplifier" },
> +       { "Left Capture Select", "Mic2", "MIC2 Pre-Amplifier" },
> +       { "Left Capture Select", "Mic1,Mic2", "MIC1 Pre-Amplifier" },
> +       { "Left Capture Select", "Mic1+Mic2", "MIC1 Pre-Amplifier" },
> +       { "Left Capture Select", "Mic1+Mic2", "MIC2 Pre-Amplifier" },
> +       { "Left Capture Select", "Output Mixer", "Left Mixer" },
> +       { "Left Capture Select", "Line,Mic1", "Line Left" },
> +       { "Left Capture Select", "Line,Mic1", "Differential Line Capture Switch" },
> +       { "Left ADC", NULL, "Left Capture Select" },
> +
> +       /* Right ADC Input Routes */
> +       { "Right Capture Select", "Line", "Line Right" },
> +       { "Right Capture Select", "Line", "Differential Line Capture Switch" },
> +       { "Right Capture Select", "FM", "FM Right" },
> +       { "Right Capture Select", "Mic1", "MIC1 Pre-Amplifier" },
> +       { "Right Capture Select", "Mic2", "MIC2 Pre-Amplifier" },
> +       { "Right Capture Select", "Mic1,Mic2", "MIC2 Pre-Amplifier" },
> +       { "Right Capture Select", "Mic1+Mic2", "MIC2 Pre-Amplifier" },
> +       { "Right Capture Select", "Mic1+Mic2", "MIC1 Pre-Amplifier" },
> +       { "Right Capture Select", "Output Mixer", "Right Mixer" },
> +       { "Right Capture Select", "Line,Mic1", "MIC1 Pre-Amplifier" },
> +       { "Right ADC", NULL, "Right Capture Select" },
>  };
>
>  static struct snd_soc_codec_driver sun4i_codec_codec = {
>         .component_driver = {
> -               .controls               = sun4i_codec_controls,
> -               .num_controls           = ARRAY_SIZE(sun4i_codec_controls),
> -               .dapm_widgets           = sun4i_codec_codec_dapm_widgets,
> -               .num_dapm_widgets       = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
> -               .dapm_routes            = sun4i_codec_codec_dapm_routes,
> -               .num_dapm_routes        = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
> +               .controls         = sun4i_codec_controls,
> +               .num_controls     = ARRAY_SIZE(sun4i_codec_controls),
> +               .dapm_widgets     = sun4i_codec_codec_dapm_widgets,
> +               .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
> +               .dapm_routes      = sun4i_codec_codec_dapm_routes,
> +               .num_dapm_routes  = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
>         },
>  };
> +
>  static struct snd_soc_codec_driver sun7i_codec_codec = {
>         .component_driver = {
> -               .controls               = sun7i_codec_controls,
> -               .num_controls           = ARRAY_SIZE(sun7i_codec_controls),
> -               .dapm_widgets           = sun4i_codec_codec_dapm_widgets,
> -               .num_dapm_widgets       = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
> -               .dapm_routes            = sun4i_codec_codec_dapm_routes,
> -               .num_dapm_routes        = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
> +               .controls         = sun7i_codec_controls,
> +               .num_controls     = ARRAY_SIZE(sun7i_codec_controls),
> +               .dapm_widgets     = sun4i_codec_codec_dapm_widgets,
> +               .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
> +               .dapm_routes      = sun4i_codec_codec_dapm_routes,
> +               .num_dapm_routes  = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),

You should put these changes in the first patch.

Note that I haven't checked the register offsets.

Regards
ChenYu

>         },
>  };
>

[toc] | [prev] | [next] | [standalone]


#1473075 — Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.

FromDanny Milosavljevic <dannym@scratchpost.org>
Date2016-08-31 09:20 +0200
SubjectRe: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.
Message-ID<sc7Yt-7LL-15@gated-at.bofh.it>
In reply to#1473058
Hi Chen-Yu,

> > +static const char * const sun4i_codec_difflinein_capture_source[] = {
> > +       "Non-Differential",
> > +       "Differential",  
> 
> How about "Stereo"? And possibly "Mono Differential"? or just "Mono".

> A differential input can be used single-ended by grounding one side.

Yes, but that's interpretation of what it's going to be used for. 
The hardware either subtracts or not, nothing more.
That said, I'll change it to "Stereo" and "Mono Differential".

> > +       SOC_SINGLE_TLV("Line Capture Volume", \
> > +                      SUN4I_CODEC_ADC_ACTL, \
> > +                      SUN4I_CODEC_ADC_ACTL_LNPREG, \
> > +                      7, \
> > +                      0, \
> > +                      sun4i_codec_linein_preamp_gain_scale)  
> 
> Nope. This is a pre-gain or boost. It affects both playback and
> capture. "Line Boost Volume" would be better.

According to Documentation/sound/alsa/ControlNames.txt that is not a valid name.
Also alsa-lib does special things depending on the control name so we are not 
free to choose here. If it were me freely choosing the names then half the
control names in this module would change.

> Same for the Mic pre-amp gain controls.

Likewise. I can see that it's confusing... but what should we do?

> I have a few patches that introduce SOC_DAPM_DOUBLE, so you can share a
> control between left/right channels. IMHO it makes the userspace mixer
> less confusing.

I agree. It would be nice to use this in the future when it's merged.
Will you post it?

> > +       /* MUX */
> > +       SND_SOC_DAPM_MUX("Left Capture Select", SND_SOC_NOPM, 0, 0,
> > +                        &sun4i_codec_capture_source_controls),
> > +       SND_SOC_DAPM_MUX("Right Capture Select", SND_SOC_NOPM, 0, 0,
> > +                        &sun4i_codec_capture_source_controls),
> > +       SND_SOC_DAPM_MUX("Differential Line Capture Switch", SND_SOC_NOPM,
> > +                        0,
> > +                        0,
> > +                        &sun4i_codec_difflinein_capture_source_controls),  
> 
> The proper function suffix is "Route", not "Select".

Indeed. Also for "Differential Line Capture Switch" except for the enum, I suppose.

> > +       /* Inputs */
> >         SND_SOC_DAPM_INPUT("Mic1"),
> > +       SND_SOC_DAPM_INPUT("Mic2"),  
> 
> How about SND_SOC_DAPM_MIC? 

What does it do differently? Seems to use different callback and all.
Is it worth changing an extensively tested patch because of it?

>And what about microphone bias?

The User Manual mentions microphone bias exactly once - in the summary.

Searching for just "bias", there's AC_ADDA_BIAS_CTRL "for DAC/ADC
performance tuning" and AC_DAC_CAL BIASCALI.
Is it one of those? How does it work?

> > +       SND_SOC_DAPM_INPUT("Line Right"),
> > +       SND_SOC_DAPM_INPUT("Line Left"),
> > +       SND_SOC_DAPM_INPUT("FM Right"),
> > +       SND_SOC_DAPM_INPUT("FM Left"),  
> 
> Why the left/right channels? 

Because they exist in hardware.
Also Mic1 and Mic2 are listed as well, so for symmetry.

> You aren't doing anything special for
> them. You could just have one Line and one FM, and have routes to
> left/right mixers.

> >  static struct snd_soc_codec_driver sun7i_codec_codec = {
> >         .component_driver = {
> > -               .controls               = sun7i_codec_controls,
> > -               .num_controls           = ARRAY_SIZE(sun7i_codec_controls),
> > -               .dapm_widgets           = sun4i_codec_codec_dapm_widgets,
> > -               .num_dapm_widgets       = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
> > -               .dapm_routes            = sun4i_codec_codec_dapm_routes,
> > -               .num_dapm_routes        = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
> > +               .controls         = sun7i_codec_controls,
> > +               .num_controls     = ARRAY_SIZE(sun7i_codec_controls),
> > +               .dapm_widgets     = sun4i_codec_codec_dapm_widgets,
> > +               .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
> > +               .dapm_routes      = sun4i_codec_codec_dapm_routes,
> > +               .num_dapm_routes  = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),  
> 
> You should put these changes in the first patch.

Indeed.

Cheers,
   Danny

[toc] | [prev] | [next] | [standalone]


#1473138 — Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.

FromChen-Yu Tsai <wens@csie.org>
Date2016-08-31 09:50 +0200
SubjectRe: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.
Message-ID<sc8rw-7Xa-5@gated-at.bofh.it>
In reply to#1473075
On Wed, Aug 31, 2016 at 3:17 PM, Danny Milosavljevic
<dannym@scratchpost.org> wrote:
> Hi Chen-Yu,
>
>> > +static const char * const sun4i_codec_difflinein_capture_source[] = {
>> > +       "Non-Differential",
>> > +       "Differential",
>>
>> How about "Stereo"? And possibly "Mono Differential"? or just "Mono".
>
>> A differential input can be used single-ended by grounding one side.
>
> Yes, but that's interpretation of what it's going to be used for.
> The hardware either subtracts or not, nothing more.
> That said, I'll change it to "Stereo" and "Mono Differential".
>
>> > +       SOC_SINGLE_TLV("Line Capture Volume", \
>> > +                      SUN4I_CODEC_ADC_ACTL, \
>> > +                      SUN4I_CODEC_ADC_ACTL_LNPREG, \
>> > +                      7, \
>> > +                      0, \
>> > +                      sun4i_codec_linein_preamp_gain_scale)
>>
>> Nope. This is a pre-gain or boost. It affects both playback and
>> capture. "Line Boost Volume" would be better.
>
> According to Documentation/sound/alsa/ControlNames.txt that is not a valid name.
> Also alsa-lib does special things depending on the control name so we are not
> free to choose here. If it were me freely choosing the names then half the
> control names in this module would change.

I saw some other drivers use "Boost Volume". Also, alsa-lib looks
for suffices, such as "Volume", "Playback Volume", "Switch", etc..

"Boost" is not part of any special name treatment. Though if you
want to follow ControlNames.txt closely, I would suggest "X Pre-Amp",
which would really be the source.

>
>> Same for the Mic pre-amp gain controls.
>
> Likewise. I can see that it's confusing... but what should we do?
>
>> I have a few patches that introduce SOC_DAPM_DOUBLE, so you can share a
>> control between left/right channels. IMHO it makes the userspace mixer
>> less confusing.
>
> I agree. It would be nice to use this in the future when it's merged.
> Will you post it?

I will, probably as part of the A31 codec series. If you really like it
I can post it first, and we both can base our patches on it.

As you mentioned ControlNames.txt, I need to revisit the A31 control
names.

>
>> > +       /* MUX */
>> > +       SND_SOC_DAPM_MUX("Left Capture Select", SND_SOC_NOPM, 0, 0,
>> > +                        &sun4i_codec_capture_source_controls),
>> > +       SND_SOC_DAPM_MUX("Right Capture Select", SND_SOC_NOPM, 0, 0,
>> > +                        &sun4i_codec_capture_source_controls),
>> > +       SND_SOC_DAPM_MUX("Differential Line Capture Switch", SND_SOC_NOPM,
>> > +                        0,
>> > +                        0,
>> > +                        &sun4i_codec_difflinein_capture_source_controls),
>>
>> The proper function suffix is "Route", not "Select".
>
> Indeed. Also for "Differential Line Capture Switch" except for the enum, I suppose.

IIRC alsa-lib checks if it's an enum first, so it would appear as the right
type of control anyway. I'm not sure though.

>
>> > +       /* Inputs */
>> >         SND_SOC_DAPM_INPUT("Mic1"),
>> > +       SND_SOC_DAPM_INPUT("Mic2"),
>>
>> How about SND_SOC_DAPM_MIC?
>
> What does it do differently? Seems to use different callback and all.
> Is it worth changing an extensively tested patch because of it?

Seems that you can tie an extra event handler to it, and it is treated
as an endpoint on a fully routed card. Neither is the case here, so
it really makes no difference. Lets keep it as INPUT for now.

Ref: On a fully routed card, INPUT/OUTPUT widgets are not endpoints.
You need to route Mic/Headphone/Speaker/Line widgets to/from them
for the whole path to work.

I might need to rethink my approach as well.

>
>>And what about microphone bias?
>
> The User Manual mentions microphone bias exactly once - in the summary.
>
> Searching for just "bias", there's AC_ADDA_BIAS_CTRL "for DAC/ADC
> performance tuning" and AC_DAC_CAL BIASCALI.
> Is it one of those? How does it work?

As I mentioned in my other reply, you did everything right in this
patch. Sorry for the noise.

>> > +       SND_SOC_DAPM_INPUT("Line Right"),
>> > +       SND_SOC_DAPM_INPUT("Line Left"),
>> > +       SND_SOC_DAPM_INPUT("FM Right"),
>> > +       SND_SOC_DAPM_INPUT("FM Left"),
>>
>> Why the left/right channels?
>
> Because they exist in hardware.
> Also Mic1 and Mic2 are listed as well, so for symmetry.
>
>> You aren't doing anything special for
>> them. You could just have one Line and one FM, and have routes to
>> left/right mixers.
>
>> >  static struct snd_soc_codec_driver sun7i_codec_codec = {
>> >         .component_driver = {
>> > -               .controls               = sun7i_codec_controls,
>> > -               .num_controls           = ARRAY_SIZE(sun7i_codec_controls),
>> > -               .dapm_widgets           = sun4i_codec_codec_dapm_widgets,
>> > -               .num_dapm_widgets       = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
>> > -               .dapm_routes            = sun4i_codec_codec_dapm_routes,
>> > -               .num_dapm_routes        = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
>> > +               .controls         = sun7i_codec_controls,
>> > +               .num_controls     = ARRAY_SIZE(sun7i_codec_controls),
>> > +               .dapm_widgets     = sun4i_codec_codec_dapm_widgets,
>> > +               .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
>> > +               .dapm_routes      = sun4i_codec_codec_dapm_routes,
>> > +               .num_dapm_routes  = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
>>
>> You should put these changes in the first patch.
>
> Indeed.
>
> Cheers,
>    Danny

Regards
ChenYu

[toc] | [prev] | [next] | [standalone]


#1473141 — Re: [linux-sunxi] Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.

FromChen-Yu Tsai <wens@csie.org>
Date2016-08-31 09:50 +0200
SubjectRe: [linux-sunxi] Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.
Message-ID<sc8rw-7Xa-15@gated-at.bofh.it>
In reply to#1473058
On Wed, Aug 31, 2016 at 3:40 PM, Danny Milosavljevic
<dannym@scratchpost.org> wrote:
>> And what about microphone bias?
>
> Would this be OK?
>
> static int sun4i_codec_handle_mic_bias_event(struct snd_soc_dapm_widget *w,
>                                              struct snd_kcontrol *k, int event)
> {
>         struct sun4i_codec *scodec = snd_soc_card_get_drvdata(w->dapm->card);
>         if (SND_SOC_DAPM_EVENT_ON(event))
>                 regmap_update_bits(scodec->regmap,
>                                    SUN4I_CODEC_ADC_ACTL,
>                                    BIT(SUN4I_CODEC_ADC_ACTL_VMICEN),
>                                    BIT(SUN4I_CODEC_ADC_ACTL_VMICEN));
>         else
>                 regmap_update_bits(scodec->regmap,
>                                    SUN4I_CODEC_ADC_ACTL,
>                                    BIT(SUN4I_CODEC_ADC_ACTL_VMICEN),
>                                    0);
> }
>
> static const struct snd_soc_dapm_widget sun4i_codec_codec_dapm_widgets[] = {
> ...
>         SND_SOC_DAPM_MIC("Mic1", sun4i_codec_handle_mic_bias_event),
>         SND_SOC_DAPM_MIC("Mic2", sun4i_codec_handle_mic_bias_event),
>
> Do I then remove
>
>          SND_SOC_DAPM_SUPPLY("VMIC", SUN4I_CODEC_ADC_ACTL,
>                             SUN4I_CODEC_ADC_ACTL_VMICEN, 0, NULL, 0),
>
> completely? What about the routes?

My apologies. I didn't notice that VMIC was already in the driver.
In that your original patch did everything right.

ChenYu

[toc] | [prev] | [next] | [standalone]


#1473146 — Re: [linux-sunxi] Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.

FromChen-Yu Tsai <wens@csie.org>
Date2016-08-31 10:00 +0200
SubjectRe: [linux-sunxi] Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.
Message-ID<sc8Bb-80v-15@gated-at.bofh.it>
In reply to#1473141
On Wed, Aug 31, 2016 at 3:49 PM, Danny Milosavljevic
<dannym@scratchpost.org> wrote:
> Hi Chen-Yu,
>
>> My apologies. I didn't notice that VMIC was already in the driver.
>> In that your original patch did everything right.
>
> Don't worry about it :)
>
> But I have a question:
>
> If I replace DAPM_INPUT by DAPM_MIC it wants a callback that is supposed to
> fiddle with the bias.
> Do I provide one?
> If so, will it conflict with the supply?
>
> Or do I leave it as DAPM_INPUT ?

I think leaving it as DAPM_INPUT will do. Also, if you use DAPM_MIC or any
other widget type that takes a callback, the callback can be NULL.

I took a quick look at other drivers. The codecs only use non-endpoint
types, like INPUT/OUTPUT. It's up to the card to provide endpoints
(HP/SPEAKER/LINE/MIC) and route them to the codec INPUT/OUTPUTs.


Regards
ChenYu

[toc] | [prev] | [next] | [standalone]


#1473150 — Re: [linux-sunxi] Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.

FromDanny Milosavljevic <dannym@scratchpost.org>
Date2016-08-31 10:00 +0200
SubjectRe: [linux-sunxi] Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.
Message-ID<sc8Bb-80v-17@gated-at.bofh.it>
In reply to#1473141
Hi Chen-Yu,
 
> My apologies. I didn't notice that VMIC was already in the driver.
> In that your original patch did everything right.

Don't worry about it :)

But I have a question:

If I replace DAPM_INPUT by DAPM_MIC it wants a callback that is supposed to
fiddle with the bias. 
Do I provide one?
If so, will it conflict with the supply?

Or do I leave it as DAPM_INPUT ?

[toc] | [prev] | [next] | [standalone]


#1473142 — Re: [linux-sunxi] Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.

FromDanny Milosavljevic <dannym@scratchpost.org>
Date2016-08-31 09:50 +0200
SubjectRe: [linux-sunxi] Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.
Message-ID<sc8rw-7Xa-17@gated-at.bofh.it>
In reply to#1473058
> And what about microphone bias?

Would this be OK?

static int sun4i_codec_handle_mic_bias_event(struct snd_soc_dapm_widget *w,
                                             struct snd_kcontrol *k, int event)
{
        struct sun4i_codec *scodec = snd_soc_card_get_drvdata(w->dapm->card);
        if (SND_SOC_DAPM_EVENT_ON(event))
                regmap_update_bits(scodec->regmap,
                                   SUN4I_CODEC_ADC_ACTL,
                                   BIT(SUN4I_CODEC_ADC_ACTL_VMICEN),
                                   BIT(SUN4I_CODEC_ADC_ACTL_VMICEN));
        else
                regmap_update_bits(scodec->regmap,
                                   SUN4I_CODEC_ADC_ACTL,
                                   BIT(SUN4I_CODEC_ADC_ACTL_VMICEN),
                                   0);
}

static const struct snd_soc_dapm_widget sun4i_codec_codec_dapm_widgets[] = {
...
        SND_SOC_DAPM_MIC("Mic1", sun4i_codec_handle_mic_bias_event),
        SND_SOC_DAPM_MIC("Mic2", sun4i_codec_handle_mic_bias_event),

Do I then remove

         SND_SOC_DAPM_SUPPLY("VMIC", SUN4I_CODEC_ADC_ACTL,
                            SUN4I_CODEC_ADC_ACTL_VMICEN, 0, NULL, 0),

completely? What about the routes?

[toc] | [prev] | [next] | [standalone]


#1474271 — Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.

FromDanny Milosavljevic <dannym@scratchpost.org>
Date2016-09-01 13:00 +0200
SubjectRe: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.
Message-ID<scxSV-H2-7@gated-at.bofh.it>
In reply to#1473058
Hi Chen-Yu,

> I have a few patches that introduce SOC_DAPM_DOUBLE, so you can share a
> control between left/right channels. IMHO it makes the userspace mixer
> less confusing.

I definitely agree that cutting down on the number of sliders would be good.
I do a double-take every time I open alsamixer - and I *added* these
sun4i widgets :)

It would be good if your patch series was queued and I could use SOC_DAPM_DOUBLE
in a future version of my patch. 

Can you post it?

Since it changes user space-visible API whether I group the widgets or not we
have to be careful about it. So far my patch has not been merged which is good
for API stability I guess.

I wondered about why there's a SOC_DOUBLE_TLV but no SOC_DAPM_DOUBLE before,
so it's good to know there's no deep reason.

That said, I'd have to remove the distinction between Left Mixer and Right
Mixer then. Right now it does distinguish. 

Removing the distinction would remove noteworthy routes like

        { "Right Mixer", "Left DAC Playback Switch", "Left DAC" },

(not a typo). Would that be OK?

Well, let's see how it will work out.

In the mean time I added the second regmap and the quirks and will post another
patch series for comments.

Cheers,
   Danny

[toc] | [prev] | [next] | [standalone]


#1474403 — Re: [linux-sunxi] Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.

FromChen-Yu Tsai <wens@csie.org>
Date2016-09-01 15:30 +0200
SubjectRe: [linux-sunxi] Re: [PATCH v9 2/2] Add mixer controls: Line-In, FM-In, Mic 2, Capture Source, Differential Line-In.
Message-ID<scAe6-2pX-15@gated-at.bofh.it>
In reply to#1474271
On Thu, Sep 1, 2016 at 6:56 PM, Danny Milosavljevic
<dannym@scratchpost.org> wrote:
> Hi Chen-Yu,
>
>> I have a few patches that introduce SOC_DAPM_DOUBLE, so you can share a
>> control between left/right channels. IMHO it makes the userspace mixer
>> less confusing.
>
> I definitely agree that cutting down on the number of sliders would be good.
> I do a double-take every time I open alsamixer - and I *added* these
> sun4i widgets :)
>
> It would be good if your patch series was queued and I could use SOC_DAPM_DOUBLE
> in a future version of my patch.
>
> Can you post it?

I'll try to make some time.

> Since it changes user space-visible API whether I group the widgets or not we
> have to be careful about it. So far my patch has not been merged which is good
> for API stability I guess.
>
> I wondered about why there's a SOC_DOUBLE_TLV but no SOC_DAPM_DOUBLE before,
> so it's good to know there's no deep reason.

AFAIU DAPM can't handle multiple channels. SOC_DAPM_ENUM_DOUBLE being the
exception, as for enums both channels are controlled together, so you don't
run into the problem of having to figure out which channel to connect or
disconnect.

> That said, I'd have to remove the distinction between Left Mixer and Right
> Mixer then. Right now it does distinguish.
>
> Removing the distinction would remove noteworthy routes like
>
>         { "Right Mixer", "Left DAC Playback Switch", "Left DAC" },
>
> (not a typo). Would that be OK?

The SOC_DAPM_DOUBLE controls are to be shared between the left/right widgets.

See: https://github.com/wens/linux/commit/ea8ce9e865635595c73bc8f7eecd711d7500f8b2

sun6i_codec_mixer_controls is shared by the "Left Mixer" and "Right Mixer"
widgets. (Not shown in the patch.)

So you would still have:

    { "Left Mixer", "DAC Playback Switch", "Left DAC" },
    { "Right Mixer", "DAC Playback Switch", "Right DAC" },

This is what the DAPM diagram looks like on my A31:

    https://wens.tw/dapm.pdf

The routes are not exported to userspace, not counting debugfs.
Only the controls are.


Hope this explains things.

Regards
ChenYu


> Well, let's see how it will work out.
>
> In the mean time I added the second regmap and the quirks and will post another
> patch series for comments.
>
> Cheers,
>    Danny
>
> --
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web