All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] [RFC] ALSA: hda: Fix the control element identification for multiple codecs
@ 2023-01-30  8:21 Jaroslav Kysela
  2023-01-31  8:42 ` Takashi Iwai
  0 siblings, 1 reply; 3+ messages in thread
From: Jaroslav Kysela @ 2023-01-30  8:21 UTC (permalink / raw)
  To: ALSA development; +Cc: Takashi Iwai

[This is a RFC for the discussion]

Some motherboards have multiple HDA codecs connected to the serial bus.
The current code may create multiple mixer controls with the almost
identical identification.

The current code use id.device field from the control element structure
to store the codec address to avoid such clashes for multiple codecs.
Unfortunately, the user space do not handle this correctly. For mixer
controls, only name and index are used for the identifiers.

This patch fixes this problem to compose the index using the codec
address as an offset in case, when the control already exists. It is
really unlikely that one codec will create 10 similar controls.

This patch adds new kernel module parameter 'ctl_dev_id' to allow
select the old behaviour, too.

BugLink: https://github.com/alsa-project/alsa-lib/issues/294
BugLink: https://github.com/alsa-project/alsa-lib/issues/205
Fixes: 54d174031576 ("[ALSA] hda-codec - Fix connection list parsing")
Fixes: 1afe206ab699 ("ALSA: hda - Try to find an empty control index when it's occupied")
Signed-off-by: Jaroslav Kysela <perex@perex.cz>

--

Discussion:

There are several possibilities to handle the old behaviour - a kernel
module parameter (proposed), a kernel configuration option or drop
the old behaviour completely.
---
 include/sound/hda_codec.h      |  1 +
 sound/pci/hda/hda_codec.c      | 13 ++++++++++---
 sound/pci/hda/hda_controller.c |  1 +
 sound/pci/hda/hda_controller.h |  1 +
 sound/pci/hda/hda_intel.c      |  5 +++++
 5 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/include/sound/hda_codec.h b/include/sound/hda_codec.h
index eba23daf2c29..bbb7805e85d8 100644
--- a/include/sound/hda_codec.h
+++ b/include/sound/hda_codec.h
@@ -259,6 +259,7 @@ struct hda_codec {
 	unsigned int relaxed_resume:1;	/* don't resume forcibly for jack */
 	unsigned int forced_resume:1; /* forced resume for jack */
 	unsigned int no_stream_clean_at_suspend:1; /* do not clean streams at suspend */
+	unsigned int ctl_dev_id:1; /* old control element id build behaviour */
 
 #ifdef CONFIG_PM
 	unsigned long power_on_acct;
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index edd653ece70d..8f20abc036bf 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -3390,7 +3390,12 @@ int snd_hda_add_new_ctls(struct hda_codec *codec,
 			kctl = snd_ctl_new1(knew, codec);
 			if (!kctl)
 				return -ENOMEM;
-			if (addr > 0)
+			/* Do not use the id.device field for MIXER elements.
+			 * This field is for real device numbers (like PCM) but codecs
+			 * are hidden components from the user space view (unrelated
+			 * to the mixer element identification).
+			 */
+			if (addr > 0 && codec->ctl_dev_id)
 				kctl->id.device = addr;
 			if (idx > 0)
 				kctl->id.index = idx;
@@ -3401,9 +3406,11 @@ int snd_hda_add_new_ctls(struct hda_codec *codec,
 			 * the codec addr; if it still fails (or it's the
 			 * primary codec), then try another control index
 			 */
-			if (!addr && codec->core.addr)
+			if (!addr && codec->core.addr) {
 				addr = codec->core.addr;
-			else if (!idx && !knew->index) {
+				if (!codec->ctl_dev_id)
+					idx += 10 * addr;
+			} else if (!idx && !knew->index) {
 				idx = find_empty_mixer_ctl_idx(codec,
 							       knew->name, 0);
 				if (idx <= 0)
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 0ff286b7b66b..083df287c1a4 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -1231,6 +1231,7 @@ int azx_probe_codecs(struct azx *chip, unsigned int max_slots)
 				continue;
 			codec->jackpoll_interval = chip->jackpoll_interval;
 			codec->beep_mode = chip->beep_mode;
+			codec->ctl_dev_id = chip->ctl_dev_id;
 			codecs++;
 		}
 	}
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h
index f5bf295eb830..8556031bcd68 100644
--- a/sound/pci/hda/hda_controller.h
+++ b/sound/pci/hda/hda_controller.h
@@ -124,6 +124,7 @@ struct azx {
 	/* HD codec */
 	int  codec_probe_mask; /* copied from probe_mask option */
 	unsigned int beep_mode;
+	bool ctl_dev_id;
 
 #ifdef CONFIG_SND_HDA_PATCH_LOADER
 	const struct firmware *fw;
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 87002670c0c9..2ef57dfa81f1 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -119,6 +119,7 @@ static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] =
 					CONFIG_SND_HDA_INPUT_BEEP_MODE};
 #endif
 static bool dmic_detect = 1;
+static bool ctl_dev_id[SNDRV_CARDS];
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
@@ -157,6 +158,8 @@ module_param(dmic_detect, bool, 0444);
 MODULE_PARM_DESC(dmic_detect, "Allow DSP driver selection (bypass this driver) "
 			     "(0=off, 1=on) (default=1); "
 		 "deprecated, use snd-intel-dspcfg.dsp_driver option instead");
+module_param_array(ctl_dev_id, bool, NULL, 0444);
+MODULE_PARM_DESC(ctl_dev_id, "Use control device identifier (based on codec address).");
 
 #ifdef CONFIG_PM
 static int param_set_xint(const char *val, const struct kernel_param *kp);
@@ -2278,6 +2281,8 @@ static int azx_probe_continue(struct azx *chip)
 	chip->beep_mode = beep_mode[dev];
 #endif
 
+	chip->ctl_dev_id = ctl_dev_id[dev];
+
 	/* create codec instances */
 	if (bus->codec_mask) {
 		err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]);
-- 
2.39.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] [RFC] ALSA: hda: Fix the control element identification for multiple codecs
  2023-01-30  8:21 [PATCH] [RFC] ALSA: hda: Fix the control element identification for multiple codecs Jaroslav Kysela
@ 2023-01-31  8:42 ` Takashi Iwai
  2023-01-31  8:58   ` Jaroslav Kysela
  0 siblings, 1 reply; 3+ messages in thread
From: Takashi Iwai @ 2023-01-31  8:42 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: ALSA development

On Mon, 30 Jan 2023 09:21:18 +0100,
Jaroslav Kysela wrote:
> 
> [This is a RFC for the discussion]
> 
> Some motherboards have multiple HDA codecs connected to the serial bus.
> The current code may create multiple mixer controls with the almost
> identical identification.
> 
> The current code use id.device field from the control element structure
> to store the codec address to avoid such clashes for multiple codecs.
> Unfortunately, the user space do not handle this correctly. For mixer
> controls, only name and index are used for the identifiers.
> 
> This patch fixes this problem to compose the index using the codec
> address as an offset in case, when the control already exists. It is
> really unlikely that one codec will create 10 similar controls.
> 
> This patch adds new kernel module parameter 'ctl_dev_id' to allow
> select the old behaviour, too.
> 
> BugLink: https://github.com/alsa-project/alsa-lib/issues/294
> BugLink: https://github.com/alsa-project/alsa-lib/issues/205
> Fixes: 54d174031576 ("[ALSA] hda-codec - Fix connection list parsing")
> Fixes: 1afe206ab699 ("ALSA: hda - Try to find an empty control index when it's occupied")
> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
> 
> --
> 
> Discussion:
> 
> There are several possibilities to handle the old behaviour - a kernel
> module parameter (proposed), a kernel configuration option or drop
> the old behaviour completely.

Dropping is likely no-go, as we don't even know whether it really
breaks or is safe, I suppose.  The module option sounds like a
feasible workaround, maybe with the default behavior defined by
kconfig.  And we can put some message for the old behavior to mention
it'll be deprecated, for example.  Then after some time, we can really
drop the old behavior, too.

One more question is which driver provides the option.  Does this
problem happen with SOF HDA driver, too?


thanks,

Takashi

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] [RFC] ALSA: hda: Fix the control element identification for multiple codecs
  2023-01-31  8:42 ` Takashi Iwai
@ 2023-01-31  8:58   ` Jaroslav Kysela
  0 siblings, 0 replies; 3+ messages in thread
From: Jaroslav Kysela @ 2023-01-31  8:58 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: ALSA development

On 31. 01. 23 9:42, Takashi Iwai wrote:
> On Mon, 30 Jan 2023 09:21:18 +0100,
> Jaroslav Kysela wrote:
>>
>> [This is a RFC for the discussion]
>>
>> Some motherboards have multiple HDA codecs connected to the serial bus.
>> The current code may create multiple mixer controls with the almost
>> identical identification.
>>
>> The current code use id.device field from the control element structure
>> to store the codec address to avoid such clashes for multiple codecs.
>> Unfortunately, the user space do not handle this correctly. For mixer
>> controls, only name and index are used for the identifiers.
>>
>> This patch fixes this problem to compose the index using the codec
>> address as an offset in case, when the control already exists. It is
>> really unlikely that one codec will create 10 similar controls.
>>
>> This patch adds new kernel module parameter 'ctl_dev_id' to allow
>> select the old behaviour, too.
>>
>> BugLink: https://github.com/alsa-project/alsa-lib/issues/294
>> BugLink: https://github.com/alsa-project/alsa-lib/issues/205
>> Fixes: 54d174031576 ("[ALSA] hda-codec - Fix connection list parsing")
>> Fixes: 1afe206ab699 ("ALSA: hda - Try to find an empty control index when it's occupied")
>> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
>>
>> --
>>
>> Discussion:
>>
>> There are several possibilities to handle the old behaviour - a kernel
>> module parameter (proposed), a kernel configuration option or drop
>> the old behaviour completely.
> 
> Dropping is likely no-go, as we don't even know whether it really
> breaks or is safe, I suppose.  The module option sounds like a
> feasible workaround, maybe with the default behavior defined by
> kconfig.  And we can put some message for the old behavior to mention
> it'll be deprecated, for example.  Then after some time, we can really
> drop the old behavior, too.

OK. I'll add a Kconfig default to my patch. I assume that the default preset 
will be the new behaviour.

> One more question is which driver provides the option.  Does this
> problem happen with SOF HDA driver, too?

I think that this hardware is rare and I've not seen this combination of HDA 
codecs with SOF yet. From the googling and the alsa-info database analysis, 
it's an old issue touching some "hi-end" ATX motherboards. Basically, 
pulseaudio nor pipewire can work with this hardware properly, because the 
mixer cannot be initialized.

					Jaroslav

-- 
Jaroslav Kysela <perex@perex.cz>
Linux Sound Maintainer; ALSA Project; Red Hat, Inc.


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-01-31  8:59 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-30  8:21 [PATCH] [RFC] ALSA: hda: Fix the control element identification for multiple codecs Jaroslav Kysela
2023-01-31  8:42 ` Takashi Iwai
2023-01-31  8:58   ` Jaroslav Kysela

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.