History

ALSA: hda: Fix the control element identification for multiple codecs

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. The CONFIG_SND_HDA_CTL_DEV_ID Kconfig option sets the default value.

Jaroslav Kysela committed 3 years ago

Commit d045bce1 parent 372a0d76 files · +32 −3Browse files

Unified · Split

6 files
  1. include/sound/hda_codec.h +1 −0
  2. sound/pci/hda/Kconfig +14 −0
  3. sound/pci/hda/hda_codec.c +10 −3
  4. sound/pci/hda/hda_controller.c +1 −0
  5. sound/pci/hda/hda_controller.h +1 −0
  6. sound/pci/hda/hda_intel.c +5 −0
include/sound/hda_codec.h+1−0
@@ -259,6 +259,7 @@ struct hda_codec { · 258 unmodified lines
259 unsigned int relaxed_resume:1; /* don't resume forcibly for jack */259 unsigned int relaxed_resume:1; /* don't resume forcibly for jack */
260 unsigned int forced_resume:1; /* forced resume for jack */260 unsigned int forced_resume:1; /* forced resume for jack */
261 unsigned int no_stream_clean_at_suspend:1; /* do not clean streams at suspend */261 unsigned int no_stream_clean_at_suspend:1; /* do not clean streams at suspend */
262 unsigned int ctl_dev_id:1; /* old control element id build behaviour */
262 263
263#ifdef CONFIG_PM264#ifdef CONFIG_PM
264 unsigned long power_on_acct;265 unsigned long power_on_acct;
sound/pci/hda/Kconfig+14−0
@@ -302,6 +302,20 @@ config SND_HDA_INTEL_HDMI_SILENT_STREAM · 301 unmodified lines
302 This feature can impact power consumption as resources302 This feature can impact power consumption as resources
303 are kept reserved both at transmitter and receiver.303 are kept reserved both at transmitter and receiver.
304 304
305config SND_HDA_CTL_DEV_ID
306 bool "Use the device identifier field for controls"
307 depends on SND_HDA_INTEL
308 help
309 Say Y to use the device identifier field for (mixer)
310 controls (old behaviour until this option is available).
311
312 When enabled, the multiple HDA codecs may set the device
313 field in control (mixer) element identifiers. The use
314 of this field is not recommended and defined for mixer controls.
315
316 The old behaviour (Y) is obsolete and will be removed. Consider
317 to not enable this option.
318
305endif319endif
306 320
307endmenu321endmenu
sound/pci/hda/hda_codec.c+10−3
@@ -3389,7 +3389,12 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, · 3388 unmodified lines
3389 kctl = snd_ctl_new1(knew, codec);3389 kctl = snd_ctl_new1(knew, codec);
3390 if (!kctl)3390 if (!kctl)
3391 return -ENOMEM;3391 return -ENOMEM;
3392 if (addr > 0)3392 /* Do not use the id.device field for MIXER elements.
3393 * This field is for real device numbers (like PCM) but codecs
3394 * are hidden components from the user space view (unrelated
3395 * to the mixer element identification).
3396 */
3397 if (addr > 0 && codec->ctl_dev_id)
3393 kctl->id.device = addr;3398 kctl->id.device = addr;
3394 if (idx > 0)3399 if (idx > 0)
3395 kctl->id.index = idx;3400 kctl->id.index = idx;
@@ -3400,9 +3405,11 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, · 4 unmodified lines
3400 * the codec addr; if it still fails (or it's the3405 * the codec addr; if it still fails (or it's the
3401 * primary codec), then try another control index3406 * primary codec), then try another control index
3402 */3407 */
3403 if (!addr && codec->core.addr)3408 if (!addr && codec->core.addr) {
3404 addr = codec->core.addr;3409 addr = codec->core.addr;
3405 else if (!idx && !knew->index) {3410 if (!codec->ctl_dev_id)
3411 idx += 10 * addr;
3412 } else if (!idx && !knew->index) {
3406 idx = find_empty_mixer_ctl_idx(codec,3413 idx = find_empty_mixer_ctl_idx(codec,
3407 knew->name, 0);3414 knew->name, 0);
3408 if (idx <= 0)3415 if (idx <= 0)
sound/pci/hda/hda_controller.c+1−0
@@ -1231,6 +1231,7 @@ int azx_probe_codecs(struct azx *chip, unsigned int max_slots) · 1230 unmodified lines
1231 continue;1231 continue;
1232 codec->jackpoll_interval = chip->jackpoll_interval;1232 codec->jackpoll_interval = chip->jackpoll_interval;
1233 codec->beep_mode = chip->beep_mode;1233 codec->beep_mode = chip->beep_mode;
1234 codec->ctl_dev_id = chip->ctl_dev_id;
1234 codecs++;1235 codecs++;
1235 }1236 }
1236 }1237 }
sound/pci/hda/hda_controller.h+1−0
@@ -124,6 +124,7 @@ struct azx { · 123 unmodified lines
124 /* HD codec */124 /* HD codec */
125 int codec_probe_mask; /* copied from probe_mask option */125 int codec_probe_mask; /* copied from probe_mask option */
126 unsigned int beep_mode;126 unsigned int beep_mode;
127 bool ctl_dev_id;
127 128
128#ifdef CONFIG_SND_HDA_PATCH_LOADER129#ifdef CONFIG_SND_HDA_PATCH_LOADER
129 const struct firmware *fw;130 const struct firmware *fw;
sound/pci/hda/hda_intel.c+5−0
@@ -119,6 +119,7 @@ static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = · 118 unmodified lines
119 CONFIG_SND_HDA_INPUT_BEEP_MODE};119 CONFIG_SND_HDA_INPUT_BEEP_MODE};
120#endif120#endif
121static bool dmic_detect = 1;121static bool dmic_detect = 1;
122static bool ctl_dev_id = IS_ENABLED(CONFIG_SND_HDA_CTL_DEV_ID) ? 1 : 0;
122 123
123module_param_array(index, int, NULL, 0444);124module_param_array(index, int, NULL, 0444);
124MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");125MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
@@ -157,6 +158,8 @@ module_param(dmic_detect, bool, 0444); · 32 unmodified lines
157MODULE_PARM_DESC(dmic_detect, "Allow DSP driver selection (bypass this driver) "158MODULE_PARM_DESC(dmic_detect, "Allow DSP driver selection (bypass this driver) "
158 "(0=off, 1=on) (default=1); "159 "(0=off, 1=on) (default=1); "
159 "deprecated, use snd-intel-dspcfg.dsp_driver option instead");160 "deprecated, use snd-intel-dspcfg.dsp_driver option instead");
161module_param(ctl_dev_id, bool, 0444);
162MODULE_PARM_DESC(ctl_dev_id, "Use control device identifier (based on codec address).");
160 163
161#ifdef CONFIG_PM164#ifdef CONFIG_PM
162static int param_set_xint(const char *val, const struct kernel_param *kp);165static int param_set_xint(const char *val, const struct kernel_param *kp);
@@ -2278,6 +2281,8 @@ static int azx_probe_continue(struct azx *chip) · 2115 unmodified lines
2278 chip->beep_mode = beep_mode[dev];2281 chip->beep_mode = beep_mode[dev];
2279#endif2282#endif
2280 2283
2284 chip->ctl_dev_id = ctl_dev_id;
2285
2281 /* create codec instances */2286 /* create codec instances */
2282 if (bus->codec_mask) {2287 if (bus->codec_mask) {
2283 err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]);2288 err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t