All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vitaly Rodionov <vitalyr@opensource.cirrus.com>
To: Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>
Cc: <alsa-devel@alsa-project.org>, <patches@opensource.cirrus.com>,
	<linux-kernel@vger.kernel.org>,
	Lucas Tanure <tanureal@opensource.cirrus.com>
Subject: [PATCH v4 12/27] ALSA: hda/cs8409: Generalize volume controls
Date: Wed, 11 Aug 2021 19:56:39 +0100	[thread overview]
Message-ID: <20210811185654.6837-13-vitalyr@opensource.cirrus.com> (raw)
In-Reply-To: <20210811185654.6837-1-vitalyr@opensource.cirrus.com>

From: Lucas Tanure <tanureal@opensource.cirrus.com>

Use amp offsets as indexes for saved volumes.
Remove dependencies on NID inside volume control functions.

Signed-off-by: Lucas Tanure <tanureal@opensource.cirrus.com>
Signed-off-by: Vitaly Rodionov <vitalyr@opensource.cirrus.com>
---

Changes in v2:
- No changes

Changes in v3:
- No changes

Changes in v4:
- No changes

 sound/pci/hda/patch_cs8409-tables.c |  37 +++++++
 sound/pci/hda/patch_cs8409.c        | 165 +++++++++-------------------
 sound/pci/hda/patch_cs8409.h        |  27 +++--
 3 files changed, 105 insertions(+), 124 deletions(-)

diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c
index 07d3ae28c105..b03ddef2a25f 100644
--- a/sound/pci/hda/patch_cs8409-tables.c
+++ b/sound/pci/hda/patch_cs8409-tables.c
@@ -10,6 +10,43 @@
 
 #include "patch_cs8409.h"
 
+/******************************************************************************
+ *                          CS42L42 Specific Data
+ *
+ ******************************************************************************/
+
+static const DECLARE_TLV_DB_SCALE(cs42l42_dac_db_scale,
+	CS8409_CS42L42_HP_VOL_REAL_MIN * 100, 100, 1);
+
+static const DECLARE_TLV_DB_SCALE(cs42l42_adc_db_scale,
+	CS8409_CS42L42_AMIC_VOL_REAL_MIN * 100, 100, 1);
+
+const struct snd_kcontrol_new cs42l42_dac_volume_mixer = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.index = 0,
+	.subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG),
+	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+	.info = cs8409_cs42l42_volume_info,
+	.get = cs8409_cs42l42_volume_get,
+	.put = cs8409_cs42l42_volume_put,
+	.tlv = { .p = cs42l42_dac_db_scale },
+	.private_value = HDA_COMPOSE_AMP_VAL_OFS(CS8409_PIN_ASP1_TRANSMITTER_A, 3, 0,
+			 HDA_OUTPUT, CS42L42_VOL_DAC) | HDA_AMP_VAL_MIN_MUTE
+};
+
+const struct snd_kcontrol_new cs42l42_adc_volume_mixer = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.index = 0,
+	.subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG),
+	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+	.info = cs8409_cs42l42_volume_info,
+	.get = cs8409_cs42l42_volume_get,
+	.put = cs8409_cs42l42_volume_put,
+	.tlv = { .p = cs42l42_adc_db_scale },
+	.private_value = HDA_COMPOSE_AMP_VAL_OFS(CS8409_PIN_ASP1_RECEIVER_A, 1, 0,
+			 HDA_INPUT, CS42L42_VOL_ADC) | HDA_AMP_VAL_MIN_MUTE
+};
+
 /* Dell Inspiron platforms
  * with cs8409 bridge and cs42l42 codec
  */
diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c
index 0b13bcecd778..08205c19698c 100644
--- a/sound/pci/hda/patch_cs8409.c
+++ b/sound/pci/hda/patch_cs8409.c
@@ -208,162 +208,97 @@ static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, u
 	return 0;
 }
 
-static int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo)
+int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo)
 {
-	u16 nid = get_amp_nid(kctrl);
+	unsigned int ofs = get_amp_offset(kctrl);
 	u8 chs = get_amp_channels(kctrl);
 
-	switch (nid) {
-	case CS8409_CS42L42_HP_PIN_NID:
-		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-		uinfo->count = chs == 3 ? 2 : 1;
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->value.integer.step = 1;
+	uinfo->count = chs == 3 ? 2 : 1;
+
+	switch (ofs) {
+	case CS42L42_VOL_DAC:
 		uinfo->value.integer.min = CS8409_CS42L42_HP_VOL_REAL_MIN;
 		uinfo->value.integer.max = CS8409_CS42L42_HP_VOL_REAL_MAX;
 		break;
-	case CS8409_CS42L42_AMIC_PIN_NID:
-		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-		uinfo->count = chs == 3 ? 2 : 1;
+	case CS42L42_VOL_ADC:
 		uinfo->value.integer.min = CS8409_CS42L42_AMIC_VOL_REAL_MIN;
 		uinfo->value.integer.max = CS8409_CS42L42_AMIC_VOL_REAL_MAX;
 		break;
 	default:
 		break;
 	}
-	return 0;
-}
 
-static void cs8409_cs42l42_update_volume(struct hda_codec *codec)
-{
-	struct cs8409_spec *spec = codec->spec;
-	int data;
-
-	mutex_lock(&spec->cs8409_i2c_mux);
-	data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHA, 1);
-	if (data >= 0)
-		spec->cs42l42_hp_volume[0] = -data;
-	else
-		spec->cs42l42_hp_volume[0] = CS8409_CS42L42_HP_VOL_REAL_MIN;
-	data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHB, 1);
-	if (data >= 0)
-		spec->cs42l42_hp_volume[1] = -data;
-	else
-		spec->cs42l42_hp_volume[1] = CS8409_CS42L42_HP_VOL_REAL_MIN;
-	data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOLUME, 1);
-	if (data >= 0)
-		spec->cs42l42_hs_mic_volume[0] = -data;
-	else
-		spec->cs42l42_hs_mic_volume[0] = CS8409_CS42L42_AMIC_VOL_REAL_MIN;
-	mutex_unlock(&spec->cs8409_i2c_mux);
-	spec->cs42l42_volume_init = 1;
+	return 0;
 }
 
-static int cs8409_cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl)
+int cs8409_cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kctrl);
 	struct cs8409_spec *spec = codec->spec;
-	hda_nid_t nid = get_amp_nid(kctrl);
 	int chs = get_amp_channels(kctrl);
+	unsigned int ofs = get_amp_offset(kctrl);
 	long *valp = uctrl->value.integer.value;
 
-	if (!spec->cs42l42_volume_init) {
-		snd_hda_power_up(codec);
-		cs8409_cs42l42_update_volume(codec);
-		snd_hda_power_down(codec);
-	}
-	switch (nid) {
-	case CS8409_CS42L42_HP_PIN_NID:
+	switch (ofs) {
+	case CS42L42_VOL_DAC:
 		if (chs & BIT(0))
-			*valp++ = spec->cs42l42_hp_volume[0];
+			*valp++ = spec->vol[ofs];
 		if (chs & BIT(1))
-			*valp++ = spec->cs42l42_hp_volume[1];
+			*valp = spec->vol[ofs+1];
 		break;
-	case CS8409_CS42L42_AMIC_PIN_NID:
+	case CS42L42_VOL_ADC:
 		if (chs & BIT(0))
-			*valp++ = spec->cs42l42_hs_mic_volume[0];
+			*valp = spec->vol[ofs];
 		break;
 	default:
 		break;
 	}
+
 	return 0;
 }
 
-static int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl)
+int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kctrl);
 	struct cs8409_spec *spec = codec->spec;
-	hda_nid_t nid = get_amp_nid(kctrl);
 	int chs = get_amp_channels(kctrl);
+	unsigned int ofs = get_amp_offset(kctrl);
 	long *valp = uctrl->value.integer.value;
-	int change = 0;
-	char vol;
 
-	snd_hda_power_up(codec);
-	switch (nid) {
-	case CS8409_CS42L42_HP_PIN_NID:
+	switch (ofs) {
+	case CS42L42_VOL_DAC:
 		mutex_lock(&spec->cs8409_i2c_mux);
 		if (chs & BIT(0)) {
-			vol = -(*valp);
-			change = cs8409_i2c_write(codec, CS42L42_I2C_ADDR,
-						  CS8409_CS42L42_REG_HS_VOLUME_CHA, vol, 1);
-			valp++;
+			spec->vol[ofs] = *valp;
+			cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA,
+					 -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1);
 		}
 		if (chs & BIT(1)) {
-			vol = -(*valp);
-			change |= cs8409_i2c_write(codec, CS42L42_I2C_ADDR,
-						   CS8409_CS42L42_REG_HS_VOLUME_CHB, vol, 1);
+			ofs++;
+			valp++;
+			spec->vol[ofs] = *valp;
+			cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB,
+					 -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1);
 		}
 		mutex_unlock(&spec->cs8409_i2c_mux);
 		break;
-	case CS8409_CS42L42_AMIC_PIN_NID:
+	case CS42L42_VOL_ADC:
 		mutex_lock(&spec->cs8409_i2c_mux);
 		if (chs & BIT(0)) {
-			change = cs8409_i2c_write(codec, CS42L42_I2C_ADDR,
-						  CS8409_CS42L42_REG_AMIC_VOLUME, (char)*valp, 1);
-			valp++;
+			spec->vol[ofs] = *valp;
+			cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL,
+					 spec->vol[ofs] & CS8409_CS42L42_REG_AMIC_VOL_MASK, 1);
 		}
 		mutex_unlock(&spec->cs8409_i2c_mux);
 		break;
 	default:
 		break;
 	}
-	cs8409_cs42l42_update_volume(codec);
-	snd_hda_power_down(codec);
-	return change;
-}
-
-static const DECLARE_TLV_DB_SCALE(cs8409_cs42l42_hp_db_scale,
-				  CS8409_CS42L42_HP_VOL_REAL_MIN * 100, 100, 1);
-
-static const DECLARE_TLV_DB_SCALE(cs8409_cs42l42_amic_db_scale,
-				  CS8409_CS42L42_AMIC_VOL_REAL_MIN * 100, 100, 1);
-
-static const struct snd_kcontrol_new cs8409_cs42l42_hp_volume_mixer = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.index = 0,
-	.name = "Headphone Playback Volume",
-	.subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG),
-	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ),
-	.info = cs8409_cs42l42_volume_info,
-	.get = cs8409_cs42l42_volume_get,
-	.put = cs8409_cs42l42_volume_put,
-	.tlv = { .p = cs8409_cs42l42_hp_db_scale },
-	.private_value = HDA_COMPOSE_AMP_VAL(CS8409_CS42L42_HP_PIN_NID, 3, 0, HDA_OUTPUT) |
-			 HDA_AMP_VAL_MIN_MUTE
-};
 
-static const struct snd_kcontrol_new cs8409_cs42l42_amic_volume_mixer = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.index = 0,
-	.name = "Mic Capture Volume",
-	.subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG),
-	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ),
-	.info = cs8409_cs42l42_volume_info,
-	.get = cs8409_cs42l42_volume_get,
-	.put = cs8409_cs42l42_volume_put,
-	.tlv = { .p = cs8409_cs42l42_amic_db_scale },
-	.private_value = HDA_COMPOSE_AMP_VAL(CS8409_CS42L42_AMIC_PIN_NID, 1, 0, HDA_INPUT) |
-			 HDA_AMP_VAL_MIN_MUTE
-};
+	return 0;
+}
 
 /* Assert/release RTS# line to CS42L42 */
 static void cs8409_cs42l42_reset(struct hda_codec *codec)
@@ -657,18 +592,14 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec)
 	}
 
 	/* Restore Volumes after Resume */
-	if (spec->cs42l42_volume_init) {
-		mutex_lock(&spec->cs8409_i2c_mux);
-		cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHA,
-				 -spec->cs42l42_hp_volume[0], 1);
-		cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHB,
-				 -spec->cs42l42_hp_volume[1], 1);
-		cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOLUME,
-				 spec->cs42l42_hs_mic_volume[0], 1);
-		mutex_unlock(&spec->cs8409_i2c_mux);
-	}
-
-	cs8409_cs42l42_update_volume(codec);
+	mutex_lock(&spec->cs8409_i2c_mux);
+	cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA,
+			 -(spec->vol[1]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1);
+	cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB,
+			 -(spec->vol[2]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1);
+	cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL,
+			 spec->vol[0] & CS8409_CS42L42_REG_AMIC_VOL_MASK, 1);
+	mutex_unlock(&spec->cs8409_i2c_mux);
 
 	cs8409_cs42l42_enable_jack_detect(codec);
 
@@ -811,8 +742,10 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix,
 		/* Set initial DMIC volume to -26 dB */
 		snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID,
 					      HDA_INPUT, 0, 0xff, 0x19);
-		snd_hda_gen_add_kctl(&spec->gen, NULL, &cs8409_cs42l42_hp_volume_mixer);
-		snd_hda_gen_add_kctl(&spec->gen, NULL, &cs8409_cs42l42_amic_volume_mixer);
+		snd_hda_gen_add_kctl(&spec->gen, "Headphone Playback Volume",
+				&cs42l42_dac_volume_mixer);
+		snd_hda_gen_add_kctl(&spec->gen, "Mic Capture Volume",
+				&cs42l42_adc_volume_mixer);
 		/* Disable Unsolicited Response during boot */
 		cs8409_enable_ur(codec, 0);
 		cs8409_cs42l42_hw_init(codec);
diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h
index 0f2084b6ec8e..bf0e8a4cc4cc 100644
--- a/sound/pci/hda/patch_cs8409.h
+++ b/sound/pci/hda/patch_cs8409.h
@@ -215,16 +215,17 @@ enum cs8409_coefficient_index_registers {
 
 /* CS42L42 Specific Definitions */
 
-#define CS42L42_HP_CH				(2U)
-#define CS42L42_HS_MIC_CH			(1U)
+#define CS42L42_VOLUMES				(4U)
 
 #define CS8409_CS42L42_HP_VOL_REAL_MIN		(-63)
 #define CS8409_CS42L42_HP_VOL_REAL_MAX		(0)
 #define CS8409_CS42L42_AMIC_VOL_REAL_MIN	(-97)
 #define CS8409_CS42L42_AMIC_VOL_REAL_MAX	(12)
-#define CS8409_CS42L42_REG_HS_VOLUME_CHA	(0x2301)
-#define CS8409_CS42L42_REG_HS_VOLUME_CHB	(0x2303)
-#define CS8409_CS42L42_REG_AMIC_VOLUME		(0x1D03)
+#define CS8409_CS42L42_REG_HS_VOL_CHA		(0x2301)
+#define CS8409_CS42L42_REG_HS_VOL_CHB		(0x2303)
+#define CS8409_CS42L42_REG_HS_VOL_MASK		(0x003F)
+#define CS8409_CS42L42_REG_AMIC_VOL		(0x1D03)
+#define CS8409_CS42L42_REG_AMIC_VOL_MASK	(0x00FF)
 #define CS42L42_HSDET_AUTO_DONE			(0x02)
 #define CS42L42_HSTYPE_MASK			(0x03)
 #define CS42L42_JACK_INSERTED			(0x0C)
@@ -248,6 +249,11 @@ enum {
 	CS8409_FIXUPS,
 };
 
+enum {
+	CS42L42_VOL_ADC,
+	CS42L42_VOL_DAC,
+};
+
 struct cs8409_i2c_param {
 	unsigned int addr;
 	unsigned int reg;
@@ -268,10 +274,8 @@ struct cs8409_spec {
 
 	unsigned int cs42l42_hp_jack_in:1;
 	unsigned int cs42l42_mic_jack_in:1;
-	unsigned int cs42l42_volume_init:1;
 	unsigned int cs42l42_suspended:1;
-	char cs42l42_hp_volume[CS42L42_HP_CH];
-	char cs42l42_hs_mic_volume[CS42L42_HS_MIC_CH];
+	s8 vol[CS42L42_VOLUMES];
 
 	struct mutex cs8409_i2c_mux;
 
@@ -280,6 +284,13 @@ struct cs8409_spec {
 			 unsigned int *res);
 };
 
+extern const struct snd_kcontrol_new cs42l42_dac_volume_mixer;
+extern const struct snd_kcontrol_new cs42l42_adc_volume_mixer;
+
+int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo);
+int cs8409_cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl);
+int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl);
+
 extern const struct snd_pci_quirk cs8409_fixup_tbl[];
 extern const struct hda_model_fixup cs8409_models[];
 extern const struct hda_fixup cs8409_fixups[];
-- 
2.25.1


WARNING: multiple messages have this Message-ID (diff)
From: Vitaly Rodionov <vitalyr@opensource.cirrus.com>
To: Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>
Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org,
	linux-kernel@vger.kernel.org,
	Lucas Tanure <tanureal@opensource.cirrus.com>
Subject: [PATCH v4 12/27] ALSA: hda/cs8409: Generalize volume controls
Date: Wed, 11 Aug 2021 19:56:39 +0100	[thread overview]
Message-ID: <20210811185654.6837-13-vitalyr@opensource.cirrus.com> (raw)
In-Reply-To: <20210811185654.6837-1-vitalyr@opensource.cirrus.com>

From: Lucas Tanure <tanureal@opensource.cirrus.com>

Use amp offsets as indexes for saved volumes.
Remove dependencies on NID inside volume control functions.

Signed-off-by: Lucas Tanure <tanureal@opensource.cirrus.com>
Signed-off-by: Vitaly Rodionov <vitalyr@opensource.cirrus.com>
---

Changes in v2:
- No changes

Changes in v3:
- No changes

Changes in v4:
- No changes

 sound/pci/hda/patch_cs8409-tables.c |  37 +++++++
 sound/pci/hda/patch_cs8409.c        | 165 +++++++++-------------------
 sound/pci/hda/patch_cs8409.h        |  27 +++--
 3 files changed, 105 insertions(+), 124 deletions(-)

diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c
index 07d3ae28c105..b03ddef2a25f 100644
--- a/sound/pci/hda/patch_cs8409-tables.c
+++ b/sound/pci/hda/patch_cs8409-tables.c
@@ -10,6 +10,43 @@
 
 #include "patch_cs8409.h"
 
+/******************************************************************************
+ *                          CS42L42 Specific Data
+ *
+ ******************************************************************************/
+
+static const DECLARE_TLV_DB_SCALE(cs42l42_dac_db_scale,
+	CS8409_CS42L42_HP_VOL_REAL_MIN * 100, 100, 1);
+
+static const DECLARE_TLV_DB_SCALE(cs42l42_adc_db_scale,
+	CS8409_CS42L42_AMIC_VOL_REAL_MIN * 100, 100, 1);
+
+const struct snd_kcontrol_new cs42l42_dac_volume_mixer = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.index = 0,
+	.subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG),
+	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+	.info = cs8409_cs42l42_volume_info,
+	.get = cs8409_cs42l42_volume_get,
+	.put = cs8409_cs42l42_volume_put,
+	.tlv = { .p = cs42l42_dac_db_scale },
+	.private_value = HDA_COMPOSE_AMP_VAL_OFS(CS8409_PIN_ASP1_TRANSMITTER_A, 3, 0,
+			 HDA_OUTPUT, CS42L42_VOL_DAC) | HDA_AMP_VAL_MIN_MUTE
+};
+
+const struct snd_kcontrol_new cs42l42_adc_volume_mixer = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.index = 0,
+	.subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG),
+	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+	.info = cs8409_cs42l42_volume_info,
+	.get = cs8409_cs42l42_volume_get,
+	.put = cs8409_cs42l42_volume_put,
+	.tlv = { .p = cs42l42_adc_db_scale },
+	.private_value = HDA_COMPOSE_AMP_VAL_OFS(CS8409_PIN_ASP1_RECEIVER_A, 1, 0,
+			 HDA_INPUT, CS42L42_VOL_ADC) | HDA_AMP_VAL_MIN_MUTE
+};
+
 /* Dell Inspiron platforms
  * with cs8409 bridge and cs42l42 codec
  */
diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c
index 0b13bcecd778..08205c19698c 100644
--- a/sound/pci/hda/patch_cs8409.c
+++ b/sound/pci/hda/patch_cs8409.c
@@ -208,162 +208,97 @@ static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, u
 	return 0;
 }
 
-static int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo)
+int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo)
 {
-	u16 nid = get_amp_nid(kctrl);
+	unsigned int ofs = get_amp_offset(kctrl);
 	u8 chs = get_amp_channels(kctrl);
 
-	switch (nid) {
-	case CS8409_CS42L42_HP_PIN_NID:
-		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-		uinfo->count = chs == 3 ? 2 : 1;
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->value.integer.step = 1;
+	uinfo->count = chs == 3 ? 2 : 1;
+
+	switch (ofs) {
+	case CS42L42_VOL_DAC:
 		uinfo->value.integer.min = CS8409_CS42L42_HP_VOL_REAL_MIN;
 		uinfo->value.integer.max = CS8409_CS42L42_HP_VOL_REAL_MAX;
 		break;
-	case CS8409_CS42L42_AMIC_PIN_NID:
-		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-		uinfo->count = chs == 3 ? 2 : 1;
+	case CS42L42_VOL_ADC:
 		uinfo->value.integer.min = CS8409_CS42L42_AMIC_VOL_REAL_MIN;
 		uinfo->value.integer.max = CS8409_CS42L42_AMIC_VOL_REAL_MAX;
 		break;
 	default:
 		break;
 	}
-	return 0;
-}
 
-static void cs8409_cs42l42_update_volume(struct hda_codec *codec)
-{
-	struct cs8409_spec *spec = codec->spec;
-	int data;
-
-	mutex_lock(&spec->cs8409_i2c_mux);
-	data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHA, 1);
-	if (data >= 0)
-		spec->cs42l42_hp_volume[0] = -data;
-	else
-		spec->cs42l42_hp_volume[0] = CS8409_CS42L42_HP_VOL_REAL_MIN;
-	data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHB, 1);
-	if (data >= 0)
-		spec->cs42l42_hp_volume[1] = -data;
-	else
-		spec->cs42l42_hp_volume[1] = CS8409_CS42L42_HP_VOL_REAL_MIN;
-	data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOLUME, 1);
-	if (data >= 0)
-		spec->cs42l42_hs_mic_volume[0] = -data;
-	else
-		spec->cs42l42_hs_mic_volume[0] = CS8409_CS42L42_AMIC_VOL_REAL_MIN;
-	mutex_unlock(&spec->cs8409_i2c_mux);
-	spec->cs42l42_volume_init = 1;
+	return 0;
 }
 
-static int cs8409_cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl)
+int cs8409_cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kctrl);
 	struct cs8409_spec *spec = codec->spec;
-	hda_nid_t nid = get_amp_nid(kctrl);
 	int chs = get_amp_channels(kctrl);
+	unsigned int ofs = get_amp_offset(kctrl);
 	long *valp = uctrl->value.integer.value;
 
-	if (!spec->cs42l42_volume_init) {
-		snd_hda_power_up(codec);
-		cs8409_cs42l42_update_volume(codec);
-		snd_hda_power_down(codec);
-	}
-	switch (nid) {
-	case CS8409_CS42L42_HP_PIN_NID:
+	switch (ofs) {
+	case CS42L42_VOL_DAC:
 		if (chs & BIT(0))
-			*valp++ = spec->cs42l42_hp_volume[0];
+			*valp++ = spec->vol[ofs];
 		if (chs & BIT(1))
-			*valp++ = spec->cs42l42_hp_volume[1];
+			*valp = spec->vol[ofs+1];
 		break;
-	case CS8409_CS42L42_AMIC_PIN_NID:
+	case CS42L42_VOL_ADC:
 		if (chs & BIT(0))
-			*valp++ = spec->cs42l42_hs_mic_volume[0];
+			*valp = spec->vol[ofs];
 		break;
 	default:
 		break;
 	}
+
 	return 0;
 }
 
-static int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl)
+int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kctrl);
 	struct cs8409_spec *spec = codec->spec;
-	hda_nid_t nid = get_amp_nid(kctrl);
 	int chs = get_amp_channels(kctrl);
+	unsigned int ofs = get_amp_offset(kctrl);
 	long *valp = uctrl->value.integer.value;
-	int change = 0;
-	char vol;
 
-	snd_hda_power_up(codec);
-	switch (nid) {
-	case CS8409_CS42L42_HP_PIN_NID:
+	switch (ofs) {
+	case CS42L42_VOL_DAC:
 		mutex_lock(&spec->cs8409_i2c_mux);
 		if (chs & BIT(0)) {
-			vol = -(*valp);
-			change = cs8409_i2c_write(codec, CS42L42_I2C_ADDR,
-						  CS8409_CS42L42_REG_HS_VOLUME_CHA, vol, 1);
-			valp++;
+			spec->vol[ofs] = *valp;
+			cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA,
+					 -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1);
 		}
 		if (chs & BIT(1)) {
-			vol = -(*valp);
-			change |= cs8409_i2c_write(codec, CS42L42_I2C_ADDR,
-						   CS8409_CS42L42_REG_HS_VOLUME_CHB, vol, 1);
+			ofs++;
+			valp++;
+			spec->vol[ofs] = *valp;
+			cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB,
+					 -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1);
 		}
 		mutex_unlock(&spec->cs8409_i2c_mux);
 		break;
-	case CS8409_CS42L42_AMIC_PIN_NID:
+	case CS42L42_VOL_ADC:
 		mutex_lock(&spec->cs8409_i2c_mux);
 		if (chs & BIT(0)) {
-			change = cs8409_i2c_write(codec, CS42L42_I2C_ADDR,
-						  CS8409_CS42L42_REG_AMIC_VOLUME, (char)*valp, 1);
-			valp++;
+			spec->vol[ofs] = *valp;
+			cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL,
+					 spec->vol[ofs] & CS8409_CS42L42_REG_AMIC_VOL_MASK, 1);
 		}
 		mutex_unlock(&spec->cs8409_i2c_mux);
 		break;
 	default:
 		break;
 	}
-	cs8409_cs42l42_update_volume(codec);
-	snd_hda_power_down(codec);
-	return change;
-}
-
-static const DECLARE_TLV_DB_SCALE(cs8409_cs42l42_hp_db_scale,
-				  CS8409_CS42L42_HP_VOL_REAL_MIN * 100, 100, 1);
-
-static const DECLARE_TLV_DB_SCALE(cs8409_cs42l42_amic_db_scale,
-				  CS8409_CS42L42_AMIC_VOL_REAL_MIN * 100, 100, 1);
-
-static const struct snd_kcontrol_new cs8409_cs42l42_hp_volume_mixer = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.index = 0,
-	.name = "Headphone Playback Volume",
-	.subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG),
-	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ),
-	.info = cs8409_cs42l42_volume_info,
-	.get = cs8409_cs42l42_volume_get,
-	.put = cs8409_cs42l42_volume_put,
-	.tlv = { .p = cs8409_cs42l42_hp_db_scale },
-	.private_value = HDA_COMPOSE_AMP_VAL(CS8409_CS42L42_HP_PIN_NID, 3, 0, HDA_OUTPUT) |
-			 HDA_AMP_VAL_MIN_MUTE
-};
 
-static const struct snd_kcontrol_new cs8409_cs42l42_amic_volume_mixer = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.index = 0,
-	.name = "Mic Capture Volume",
-	.subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG),
-	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ),
-	.info = cs8409_cs42l42_volume_info,
-	.get = cs8409_cs42l42_volume_get,
-	.put = cs8409_cs42l42_volume_put,
-	.tlv = { .p = cs8409_cs42l42_amic_db_scale },
-	.private_value = HDA_COMPOSE_AMP_VAL(CS8409_CS42L42_AMIC_PIN_NID, 1, 0, HDA_INPUT) |
-			 HDA_AMP_VAL_MIN_MUTE
-};
+	return 0;
+}
 
 /* Assert/release RTS# line to CS42L42 */
 static void cs8409_cs42l42_reset(struct hda_codec *codec)
@@ -657,18 +592,14 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec)
 	}
 
 	/* Restore Volumes after Resume */
-	if (spec->cs42l42_volume_init) {
-		mutex_lock(&spec->cs8409_i2c_mux);
-		cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHA,
-				 -spec->cs42l42_hp_volume[0], 1);
-		cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHB,
-				 -spec->cs42l42_hp_volume[1], 1);
-		cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOLUME,
-				 spec->cs42l42_hs_mic_volume[0], 1);
-		mutex_unlock(&spec->cs8409_i2c_mux);
-	}
-
-	cs8409_cs42l42_update_volume(codec);
+	mutex_lock(&spec->cs8409_i2c_mux);
+	cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA,
+			 -(spec->vol[1]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1);
+	cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB,
+			 -(spec->vol[2]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1);
+	cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL,
+			 spec->vol[0] & CS8409_CS42L42_REG_AMIC_VOL_MASK, 1);
+	mutex_unlock(&spec->cs8409_i2c_mux);
 
 	cs8409_cs42l42_enable_jack_detect(codec);
 
@@ -811,8 +742,10 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix,
 		/* Set initial DMIC volume to -26 dB */
 		snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID,
 					      HDA_INPUT, 0, 0xff, 0x19);
-		snd_hda_gen_add_kctl(&spec->gen, NULL, &cs8409_cs42l42_hp_volume_mixer);
-		snd_hda_gen_add_kctl(&spec->gen, NULL, &cs8409_cs42l42_amic_volume_mixer);
+		snd_hda_gen_add_kctl(&spec->gen, "Headphone Playback Volume",
+				&cs42l42_dac_volume_mixer);
+		snd_hda_gen_add_kctl(&spec->gen, "Mic Capture Volume",
+				&cs42l42_adc_volume_mixer);
 		/* Disable Unsolicited Response during boot */
 		cs8409_enable_ur(codec, 0);
 		cs8409_cs42l42_hw_init(codec);
diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h
index 0f2084b6ec8e..bf0e8a4cc4cc 100644
--- a/sound/pci/hda/patch_cs8409.h
+++ b/sound/pci/hda/patch_cs8409.h
@@ -215,16 +215,17 @@ enum cs8409_coefficient_index_registers {
 
 /* CS42L42 Specific Definitions */
 
-#define CS42L42_HP_CH				(2U)
-#define CS42L42_HS_MIC_CH			(1U)
+#define CS42L42_VOLUMES				(4U)
 
 #define CS8409_CS42L42_HP_VOL_REAL_MIN		(-63)
 #define CS8409_CS42L42_HP_VOL_REAL_MAX		(0)
 #define CS8409_CS42L42_AMIC_VOL_REAL_MIN	(-97)
 #define CS8409_CS42L42_AMIC_VOL_REAL_MAX	(12)
-#define CS8409_CS42L42_REG_HS_VOLUME_CHA	(0x2301)
-#define CS8409_CS42L42_REG_HS_VOLUME_CHB	(0x2303)
-#define CS8409_CS42L42_REG_AMIC_VOLUME		(0x1D03)
+#define CS8409_CS42L42_REG_HS_VOL_CHA		(0x2301)
+#define CS8409_CS42L42_REG_HS_VOL_CHB		(0x2303)
+#define CS8409_CS42L42_REG_HS_VOL_MASK		(0x003F)
+#define CS8409_CS42L42_REG_AMIC_VOL		(0x1D03)
+#define CS8409_CS42L42_REG_AMIC_VOL_MASK	(0x00FF)
 #define CS42L42_HSDET_AUTO_DONE			(0x02)
 #define CS42L42_HSTYPE_MASK			(0x03)
 #define CS42L42_JACK_INSERTED			(0x0C)
@@ -248,6 +249,11 @@ enum {
 	CS8409_FIXUPS,
 };
 
+enum {
+	CS42L42_VOL_ADC,
+	CS42L42_VOL_DAC,
+};
+
 struct cs8409_i2c_param {
 	unsigned int addr;
 	unsigned int reg;
@@ -268,10 +274,8 @@ struct cs8409_spec {
 
 	unsigned int cs42l42_hp_jack_in:1;
 	unsigned int cs42l42_mic_jack_in:1;
-	unsigned int cs42l42_volume_init:1;
 	unsigned int cs42l42_suspended:1;
-	char cs42l42_hp_volume[CS42L42_HP_CH];
-	char cs42l42_hs_mic_volume[CS42L42_HS_MIC_CH];
+	s8 vol[CS42L42_VOLUMES];
 
 	struct mutex cs8409_i2c_mux;
 
@@ -280,6 +284,13 @@ struct cs8409_spec {
 			 unsigned int *res);
 };
 
+extern const struct snd_kcontrol_new cs42l42_dac_volume_mixer;
+extern const struct snd_kcontrol_new cs42l42_adc_volume_mixer;
+
+int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo);
+int cs8409_cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl);
+int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl);
+
 extern const struct snd_pci_quirk cs8409_fixup_tbl[];
 extern const struct hda_model_fixup cs8409_models[];
 extern const struct hda_fixup cs8409_fixups[];
-- 
2.25.1


  parent reply	other threads:[~2021-08-11 19:13 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-11 18:56 [PATCH v4 00/27] ALSA: hda/cirrus: Split generic cirrus HDA codecs and CS8490 bridge into separate modules Vitaly Rodionov
2021-08-11 18:56 ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 01/27] ALSA: hda/cirrus: Move CS8409 HDA bridge to separate module Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 02/27] ALSA: hda/cs8409: Move arrays of configuration to a new file Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 03/27] ALSA: hda/cs8409: Use enums for register names and coefficients Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 04/27] ALSA: hda/cs8409: Mask all CS42L42 interrupts on initialization Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 05/27] ALSA: hda/cs8409: Reduce HS pops/clicks for Cyborg Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 06/27] ALSA: hda/cs8409: Disable unnecessary Ring Sense for Cyborg/Warlock/Bullseye Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 07/27] ALSA: hda/cs8409: Disable unsolicited responses during suspend Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 08/27] ALSA: hda/cs8409: Disable unsolicited response for the first boot Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 09/27] ALSA: hda/cs8409: Mask CS42L42 wake events Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 10/27] ALSA: hda/cs8409: Simplify CS42L42 jack detect Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 11/27] ALSA: hda/cs8409: Prevent I2C access during suspend time Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` Vitaly Rodionov [this message]
2021-08-11 18:56   ` [PATCH v4 12/27] ALSA: hda/cs8409: Generalize volume controls Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 13/27] ALSA: hda/cs8409: Dont disable I2C clock between consecutive accesses Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 14/27] ALSA: hda/cs8409: Avoid setting the same I2C address for every access Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 15/27] ALSA: hda/cs8409: Avoid re-setting the same page as the last access Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 16/27] ALSA: hda/cs8409: Support i2c bulk read/write functions Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 17/27] ALSA: hda/cs8409: Separate CS8409, CS42L42 and project functions Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 18/27] ALSA: hda/cs8409: Move codec properties to its own struct Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 19/27] ALSA: hda/cs8409: Support multiple sub_codecs for Suspend/Resume/Unsol events Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 20/27] ALSA: hda/cs8409: Add Support to disable jack type detection for CS42L42 Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 21/27] ALSA: hda/cs8409: Add support for dolphin Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 22/27] ALSA: hda/cs8409: Enable Full Scale Volume for Line Out Codec on Dolphin Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 23/27] ALSA: hda/cs8409: Set fixed sample rate of 48kHz for CS42L42 Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 24/27] ALSA: hda/cs8409: Use timeout rather than retries for I2C transaction waits Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 25/27] ALSA: hda/cs8409: Remove unnecessary delays Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 26/27] ALSA: hda/cs8409: Follow correct CS42L42 power down sequence for suspend Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-11 18:56 ` [PATCH v4 27/27] ALSA: hda/cs8409: Unmute/Mute codec when stream starts/stops Vitaly Rodionov
2021-08-11 18:56   ` Vitaly Rodionov
2021-08-12 11:47 ` [PATCH v4 00/27] ALSA: hda/cirrus: Split generic cirrus HDA codecs and CS8490 bridge into separate modules Takashi Iwai
2021-08-12 11:47   ` Takashi Iwai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210811185654.6837-13-vitalyr@opensource.cirrus.com \
    --to=vitalyr@opensource.cirrus.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=patches@opensource.cirrus.com \
    --cc=perex@perex.cz \
    --cc=tanureal@opensource.cirrus.com \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.