[ALSA] hda-codec - Fix invalid access to non-existing dmux on STAC
The digital mux on STAC codecs doesn't always exist although the
driver builds dmux enum mixer elements unconditionally.
Now the driver creates 'digital input source' mixer elements only
when dmux is available.
Also, the patch adds the missing dmux definition for STAC925x.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 1e2d3bf..a074155 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -139,6 +139,7 @@
hda_nid_t *dmic_nids;
unsigned int num_dmics;
hda_nid_t *dmux_nids;
+ unsigned int num_dmuxes;
hda_nid_t dig_in_nid;
/* pin widgets */
@@ -244,6 +245,10 @@
0x15, 0
};
+static hda_nid_t stac925x_dmux_nids[1] = {
+ 0x14,
+};
+
static hda_nid_t stac922x_adc_nids[2] = {
0x06, 0x07,
};
@@ -278,7 +283,7 @@
};
static hda_nid_t stac9205_dmux_nids[1] = {
- 0x1d,
+ 0x1d,
};
#define STAC9205_NUM_DMICS 2
@@ -596,16 +601,6 @@
{}
};
-#define STAC_DIGITAL_INPUT_SOURCE(cnt) \
- { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = "Digital Input Source", \
- .count = cnt, \
- .info = stac92xx_dmux_enum_info, \
- .get = stac92xx_dmux_enum_get, \
- .put = stac92xx_dmux_enum_put,\
- }
-
#define STAC_INPUT_SOURCE(cnt) \
{ \
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
@@ -638,7 +633,6 @@
};
static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = {
- STAC_DIGITAL_INPUT_SOURCE(2),
STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3),
/* hardware gain controls */
@@ -669,7 +663,6 @@
};
static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = {
- STAC_DIGITAL_INPUT_SOURCE(2),
STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4),
/* hardware gain controls */
@@ -700,7 +693,6 @@
};
static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = {
- STAC_DIGITAL_INPUT_SOURCE(2),
STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5),
/* hardware gain controls */
@@ -731,7 +723,6 @@
};
static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = {
- STAC_DIGITAL_INPUT_SOURCE(1),
STAC_INPUT_SOURCE(2),
/* hardware gain controls */
@@ -752,7 +743,6 @@
};
static struct snd_kcontrol_new stac92hd71bxx_mixer[] = {
- STAC_DIGITAL_INPUT_SOURCE(1),
STAC_INPUT_SOURCE(2),
STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2),
@@ -779,7 +769,6 @@
};
static struct snd_kcontrol_new stac9205_mixer[] = {
- STAC_DIGITAL_INPUT_SOURCE(1),
STAC_INPUT_SOURCE(2),
STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1),
@@ -809,7 +798,6 @@
static struct snd_kcontrol_new stac927x_mixer[] = {
- STAC_DIGITAL_INPUT_SOURCE(1),
STAC_INPUT_SOURCE(3),
STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1),
@@ -827,6 +815,15 @@
{ } /* end */
};
+static struct snd_kcontrol_new stac_dmux_mixer = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Digital Input Source",
+ /* count set later */
+ .info = stac92xx_dmux_enum_info,
+ .get = stac92xx_dmux_enum_get,
+ .put = stac92xx_dmux_enum_put,
+};
+
static int stac92xx_build_controls(struct hda_codec *codec)
{
struct sigmatel_spec *spec = codec->spec;
@@ -842,6 +839,13 @@
if (err < 0)
return err;
}
+ if (spec->num_dmuxes > 0) {
+ stac_dmux_mixer.count = spec->num_dmuxes;
+ err = snd_ctl_add(codec->bus->card,
+ snd_ctl_new1(&stac_dmux_mixer, codec));
+ if (err < 0)
+ return err;
+ }
if (spec->multiout.dig_out_nid) {
err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
@@ -2967,6 +2971,8 @@
case 0x83847637: /* STAC9251D */
spec->num_dmics = STAC925X_NUM_DMICS;
spec->dmic_nids = stac925x_dmic_nids;
+ spec->num_dmuxes = ARRAY_SIZE(stac925x_dmux_nids);
+ spec->dmux_nids = stac925x_dmux_nids;
break;
default:
spec->num_dmics = 0;
@@ -3075,6 +3081,7 @@
spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids);
spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids);
spec->num_dmics = STAC92HD73XX_NUM_DMICS;
+ spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids);
spec->dinput_mux = &stac92hd73xx_dmux;
/* GPIO0 High = Enable EAPD */
spec->gpio_mask = spec->gpio_data = 0x000001;
@@ -3160,6 +3167,7 @@
spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids);
spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids);
spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
+ spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
spec->multiout.num_dacs = 2;
spec->multiout.hp_nid = 0x11;
@@ -3345,6 +3353,7 @@
spec->init = d965_core_init;
spec->mixer = stac927x_mixer;
spec->dmux_nids = stac927x_dmux_nids;
+ spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
break;
default:
/* GPIO0 High = Enable EAPD */
@@ -3415,6 +3424,7 @@
spec->dmic_nids = stac9205_dmic_nids;
spec->num_dmics = STAC9205_NUM_DMICS;
spec->dmux_nids = stac9205_dmux_nids;
+ spec->num_dmuxes = ARRAY_SIZE(stac9205_dmux_nids);
spec->init = stac9205_core_init;
spec->mixer = stac9205_mixer;