diff options
author | Jaroslav Kysela <perex@perex.cz> | 2009-12-08 10:13:32 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2009-12-15 03:33:04 -0500 |
commit | 5b0cb1d850c26893b1468b3a519433a1b7a176be (patch) | |
tree | c6f4ab97db6de9230b02d6cfce8976b762f3b485 /sound/pci/hda/patch_via.c | |
parent | f40542532e96dda5506eb76badea322f2ae4731c (diff) |
ALSA: hda - add more NID->Control mapping
This set of changes add missing NID values to some static control
elemenents. Also, it handles all "Capture Source" or "Input Source"
controls.
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/pci/hda/patch_via.c')
-rw-r--r-- | sound/pci/hda/patch_via.c | 273 |
1 files changed, 166 insertions, 107 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index b70e26ad263f..64995e8e3a72 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -54,6 +54,8 @@ | |||
54 | #include "hda_codec.h" | 54 | #include "hda_codec.h" |
55 | #include "hda_local.h" | 55 | #include "hda_local.h" |
56 | 56 | ||
57 | #define NID_MAPPING (-1) | ||
58 | |||
57 | /* amp values */ | 59 | /* amp values */ |
58 | #define AMP_VAL_IDX_SHIFT 19 | 60 | #define AMP_VAL_IDX_SHIFT 19 |
59 | #define AMP_VAL_IDX_MASK (0x0f<<19) | 61 | #define AMP_VAL_IDX_MASK (0x0f<<19) |
@@ -157,6 +159,19 @@ struct via_spec { | |||
157 | #endif | 159 | #endif |
158 | }; | 160 | }; |
159 | 161 | ||
162 | static struct via_spec * via_new_spec(struct hda_codec *codec) | ||
163 | { | ||
164 | struct via_spec *spec; | ||
165 | |||
166 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
167 | if (spec == NULL) | ||
168 | return NULL; | ||
169 | |||
170 | codec->spec = spec; | ||
171 | spec->codec = codec; | ||
172 | return spec; | ||
173 | } | ||
174 | |||
160 | static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec) | 175 | static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec) |
161 | { | 176 | { |
162 | u32 vendor_id = codec->vendor_id; | 177 | u32 vendor_id = codec->vendor_id; |
@@ -448,6 +463,22 @@ static int via_add_control(struct via_spec *spec, int type, const char *name, | |||
448 | return 0; | 463 | return 0; |
449 | } | 464 | } |
450 | 465 | ||
466 | static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec, | ||
467 | struct snd_kcontrol_new *tmpl) | ||
468 | { | ||
469 | struct snd_kcontrol_new *knew; | ||
470 | |||
471 | snd_array_init(&spec->kctls, sizeof(*knew), 32); | ||
472 | knew = snd_array_new(&spec->kctls); | ||
473 | if (!knew) | ||
474 | return NULL; | ||
475 | *knew = *tmpl; | ||
476 | knew->name = kstrdup(tmpl->name, GFP_KERNEL); | ||
477 | if (!knew->name) | ||
478 | return NULL; | ||
479 | return 0; | ||
480 | } | ||
481 | |||
451 | static void via_free_kctls(struct hda_codec *codec) | 482 | static void via_free_kctls(struct hda_codec *codec) |
452 | { | 483 | { |
453 | struct via_spec *spec = codec->spec; | 484 | struct via_spec *spec = codec->spec; |
@@ -1088,24 +1119,9 @@ static int via_independent_hp_get(struct snd_kcontrol *kcontrol, | |||
1088 | struct snd_ctl_elem_value *ucontrol) | 1119 | struct snd_ctl_elem_value *ucontrol) |
1089 | { | 1120 | { |
1090 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1121 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1091 | struct via_spec *spec = codec->spec; | 1122 | hda_nid_t nid = kcontrol->private_value; |
1092 | hda_nid_t nid; | ||
1093 | unsigned int pinsel; | 1123 | unsigned int pinsel; |
1094 | 1124 | ||
1095 | switch (spec->codec_type) { | ||
1096 | case VT1718S: | ||
1097 | nid = 0x34; | ||
1098 | break; | ||
1099 | case VT2002P: | ||
1100 | nid = 0x35; | ||
1101 | break; | ||
1102 | case VT1812: | ||
1103 | nid = 0x3d; | ||
1104 | break; | ||
1105 | default: | ||
1106 | nid = spec->autocfg.hp_pins[0]; | ||
1107 | break; | ||
1108 | } | ||
1109 | /* use !! to translate conn sel 2 for VT1718S */ | 1125 | /* use !! to translate conn sel 2 for VT1718S */ |
1110 | pinsel = !!snd_hda_codec_read(codec, nid, 0, | 1126 | pinsel = !!snd_hda_codec_read(codec, nid, 0, |
1111 | AC_VERB_GET_CONNECT_SEL, | 1127 | AC_VERB_GET_CONNECT_SEL, |
@@ -1127,29 +1143,24 @@ static void activate_ctl(struct hda_codec *codec, const char *name, int active) | |||
1127 | } | 1143 | } |
1128 | } | 1144 | } |
1129 | 1145 | ||
1146 | static hda_nid_t side_mute_channel(struct via_spec *spec) | ||
1147 | { | ||
1148 | switch (spec->codec_type) { | ||
1149 | case VT1708: return 0x1b; | ||
1150 | case VT1709_10CH: return 0x29; | ||
1151 | case VT1708B_8CH: /* fall thru */ | ||
1152 | case VT1708S: return 0x27; | ||
1153 | default: return 0; | ||
1154 | } | ||
1155 | } | ||
1156 | |||
1130 | static int update_side_mute_status(struct hda_codec *codec) | 1157 | static int update_side_mute_status(struct hda_codec *codec) |
1131 | { | 1158 | { |
1132 | /* mute side channel */ | 1159 | /* mute side channel */ |
1133 | struct via_spec *spec = codec->spec; | 1160 | struct via_spec *spec = codec->spec; |
1134 | unsigned int parm = spec->hp_independent_mode | 1161 | unsigned int parm = spec->hp_independent_mode |
1135 | ? AMP_OUT_MUTE : AMP_OUT_UNMUTE; | 1162 | ? AMP_OUT_MUTE : AMP_OUT_UNMUTE; |
1136 | hda_nid_t sw3; | 1163 | hda_nid_t sw3 = side_mute_channel(spec); |
1137 | |||
1138 | switch (spec->codec_type) { | ||
1139 | case VT1708: | ||
1140 | sw3 = 0x1b; | ||
1141 | break; | ||
1142 | case VT1709_10CH: | ||
1143 | sw3 = 0x29; | ||
1144 | break; | ||
1145 | case VT1708B_8CH: | ||
1146 | case VT1708S: | ||
1147 | sw3 = 0x27; | ||
1148 | break; | ||
1149 | default: | ||
1150 | sw3 = 0; | ||
1151 | break; | ||
1152 | } | ||
1153 | 1164 | ||
1154 | if (sw3) | 1165 | if (sw3) |
1155 | snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 1166 | snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
@@ -1162,28 +1173,11 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol, | |||
1162 | { | 1173 | { |
1163 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1174 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1164 | struct via_spec *spec = codec->spec; | 1175 | struct via_spec *spec = codec->spec; |
1165 | hda_nid_t nid = spec->autocfg.hp_pins[0]; | 1176 | hda_nid_t nid = kcontrol->private_value; |
1166 | unsigned int pinsel = ucontrol->value.enumerated.item[0]; | 1177 | unsigned int pinsel = ucontrol->value.enumerated.item[0]; |
1167 | /* Get Independent Mode index of headphone pin widget */ | 1178 | /* Get Independent Mode index of headphone pin widget */ |
1168 | spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel | 1179 | spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel |
1169 | ? 1 : 0; | 1180 | ? 1 : 0; |
1170 | |||
1171 | switch (spec->codec_type) { | ||
1172 | case VT1718S: | ||
1173 | nid = 0x34; | ||
1174 | pinsel = pinsel ? 2 : 0; /* indep HP use AOW4 (index 2) */ | ||
1175 | spec->multiout.num_dacs = 4; | ||
1176 | break; | ||
1177 | case VT2002P: | ||
1178 | nid = 0x35; | ||
1179 | break; | ||
1180 | case VT1812: | ||
1181 | nid = 0x3d; | ||
1182 | break; | ||
1183 | default: | ||
1184 | nid = spec->autocfg.hp_pins[0]; | ||
1185 | break; | ||
1186 | } | ||
1187 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel); | 1181 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel); |
1188 | 1182 | ||
1189 | if (spec->multiout.hp_nid && spec->multiout.hp_nid | 1183 | if (spec->multiout.hp_nid && spec->multiout.hp_nid |
@@ -1207,18 +1201,55 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol, | |||
1207 | return 0; | 1201 | return 0; |
1208 | } | 1202 | } |
1209 | 1203 | ||
1210 | static struct snd_kcontrol_new via_hp_mixer[] = { | 1204 | static struct snd_kcontrol_new via_hp_mixer[2] = { |
1211 | { | 1205 | { |
1212 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1206 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1213 | .name = "Independent HP", | 1207 | .name = "Independent HP", |
1214 | .count = 1, | ||
1215 | .info = via_independent_hp_info, | 1208 | .info = via_independent_hp_info, |
1216 | .get = via_independent_hp_get, | 1209 | .get = via_independent_hp_get, |
1217 | .put = via_independent_hp_put, | 1210 | .put = via_independent_hp_put, |
1218 | }, | 1211 | }, |
1219 | { } /* end */ | 1212 | { |
1213 | .iface = NID_MAPPING, | ||
1214 | .name = "Independent HP", | ||
1215 | }, | ||
1220 | }; | 1216 | }; |
1221 | 1217 | ||
1218 | static int via_hp_build(struct via_spec *spec) | ||
1219 | { | ||
1220 | struct snd_kcontrol_new *knew; | ||
1221 | hda_nid_t nid; | ||
1222 | |||
1223 | knew = via_clone_control(spec, &via_hp_mixer[0]); | ||
1224 | if (knew == NULL) | ||
1225 | return -ENOMEM; | ||
1226 | |||
1227 | switch (spec->codec_type) { | ||
1228 | case VT1718S: | ||
1229 | nid = 0x34; | ||
1230 | break; | ||
1231 | case VT2002P: | ||
1232 | nid = 0x35; | ||
1233 | break; | ||
1234 | case VT1812: | ||
1235 | nid = 0x3d; | ||
1236 | break; | ||
1237 | default: | ||
1238 | nid = spec->autocfg.hp_pins[0]; | ||
1239 | break; | ||
1240 | } | ||
1241 | |||
1242 | knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; | ||
1243 | knew->private_value = nid; | ||
1244 | |||
1245 | knew = via_clone_control(spec, &via_hp_mixer[1]); | ||
1246 | if (knew == NULL) | ||
1247 | return -ENOMEM; | ||
1248 | knew->subdevice = side_mute_channel(spec); | ||
1249 | |||
1250 | return 0; | ||
1251 | } | ||
1252 | |||
1222 | static void notify_aa_path_ctls(struct hda_codec *codec) | 1253 | static void notify_aa_path_ctls(struct hda_codec *codec) |
1223 | { | 1254 | { |
1224 | int i; | 1255 | int i; |
@@ -1376,7 +1407,7 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol, | |||
1376 | return 1; | 1407 | return 1; |
1377 | } | 1408 | } |
1378 | 1409 | ||
1379 | static struct snd_kcontrol_new via_smart51_mixer[] = { | 1410 | static struct snd_kcontrol_new via_smart51_mixer[2] = { |
1380 | { | 1411 | { |
1381 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1412 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1382 | .name = "Smart 5.1", | 1413 | .name = "Smart 5.1", |
@@ -1385,9 +1416,36 @@ static struct snd_kcontrol_new via_smart51_mixer[] = { | |||
1385 | .get = via_smart51_get, | 1416 | .get = via_smart51_get, |
1386 | .put = via_smart51_put, | 1417 | .put = via_smart51_put, |
1387 | }, | 1418 | }, |
1388 | {} /* end */ | 1419 | { |
1420 | .iface = NID_MAPPING, | ||
1421 | .name = "Smart 5.1", | ||
1422 | } | ||
1389 | }; | 1423 | }; |
1390 | 1424 | ||
1425 | static int via_smart51_build(struct via_spec *spec) | ||
1426 | { | ||
1427 | struct snd_kcontrol_new *knew; | ||
1428 | int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE }; | ||
1429 | hda_nid_t nid; | ||
1430 | int i; | ||
1431 | |||
1432 | knew = via_clone_control(spec, &via_smart51_mixer[0]); | ||
1433 | if (knew == NULL) | ||
1434 | return -ENOMEM; | ||
1435 | |||
1436 | for (i = 0; i < ARRAY_SIZE(index); i++) { | ||
1437 | nid = spec->autocfg.input_pins[index[i]]; | ||
1438 | if (nid) { | ||
1439 | knew = via_clone_control(spec, &via_smart51_mixer[1]); | ||
1440 | if (knew == NULL) | ||
1441 | return -ENOMEM; | ||
1442 | knew->subdevice = nid; | ||
1443 | } | ||
1444 | } | ||
1445 | |||
1446 | return 0; | ||
1447 | } | ||
1448 | |||
1391 | /* capture mixer elements */ | 1449 | /* capture mixer elements */ |
1392 | static struct snd_kcontrol_new vt1708_capture_mixer[] = { | 1450 | static struct snd_kcontrol_new vt1708_capture_mixer[] = { |
1393 | HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), | 1451 | HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), |
@@ -1819,8 +1877,9 @@ static struct hda_pcm_stream vt1708_pcm_digital_capture = { | |||
1819 | static int via_build_controls(struct hda_codec *codec) | 1877 | static int via_build_controls(struct hda_codec *codec) |
1820 | { | 1878 | { |
1821 | struct via_spec *spec = codec->spec; | 1879 | struct via_spec *spec = codec->spec; |
1822 | int err; | 1880 | struct snd_kcontrol *kctl; |
1823 | int i; | 1881 | struct snd_kcontrol_new *knew; |
1882 | int err, i; | ||
1824 | 1883 | ||
1825 | for (i = 0; i < spec->num_mixers; i++) { | 1884 | for (i = 0; i < spec->num_mixers; i++) { |
1826 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); | 1885 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); |
@@ -1845,6 +1904,28 @@ static int via_build_controls(struct hda_codec *codec) | |||
1845 | return err; | 1904 | return err; |
1846 | } | 1905 | } |
1847 | 1906 | ||
1907 | /* assign Capture Source enums to NID */ | ||
1908 | kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); | ||
1909 | for (i = 0; kctl && i < kctl->count; i++) { | ||
1910 | err = snd_hda_add_nids(codec, kctl, i, spec->mux_nids, | ||
1911 | spec->input_mux->num_items); | ||
1912 | if (err < 0) | ||
1913 | return err; | ||
1914 | } | ||
1915 | |||
1916 | /* other nid->control mapping */ | ||
1917 | for (i = 0; i < spec->num_mixers; i++) { | ||
1918 | for (knew = spec->mixers[i]; knew->name; knew++) { | ||
1919 | if (knew->iface != NID_MAPPING) | ||
1920 | continue; | ||
1921 | kctl = snd_hda_find_mixer_ctl(codec, knew->name); | ||
1922 | if (kctl == NULL) | ||
1923 | continue; | ||
1924 | err = snd_hda_add_nid(codec, kctl, 0, | ||
1925 | knew->subdevice); | ||
1926 | } | ||
1927 | } | ||
1928 | |||
1848 | /* init power states */ | 1929 | /* init power states */ |
1849 | set_jack_power_state(codec); | 1930 | set_jack_power_state(codec); |
1850 | analog_low_current_mode(codec, 1); | 1931 | analog_low_current_mode(codec, 1); |
@@ -2481,9 +2562,9 @@ static int vt1708_parse_auto_config(struct hda_codec *codec) | |||
2481 | spec->input_mux = &spec->private_imux[0]; | 2562 | spec->input_mux = &spec->private_imux[0]; |
2482 | 2563 | ||
2483 | if (spec->hp_mux) | 2564 | if (spec->hp_mux) |
2484 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 2565 | via_hp_build(spec); |
2485 | 2566 | ||
2486 | spec->mixers[spec->num_mixers++] = via_smart51_mixer; | 2567 | via_smart51_build(spec); |
2487 | return 1; | 2568 | return 1; |
2488 | } | 2569 | } |
2489 | 2570 | ||
@@ -2554,12 +2635,10 @@ static int patch_vt1708(struct hda_codec *codec) | |||
2554 | int err; | 2635 | int err; |
2555 | 2636 | ||
2556 | /* create a codec specific record */ | 2637 | /* create a codec specific record */ |
2557 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 2638 | spec = via_new_spec(codec); |
2558 | if (spec == NULL) | 2639 | if (spec == NULL) |
2559 | return -ENOMEM; | 2640 | return -ENOMEM; |
2560 | 2641 | ||
2561 | codec->spec = spec; | ||
2562 | |||
2563 | /* automatic parse from the BIOS config */ | 2642 | /* automatic parse from the BIOS config */ |
2564 | err = vt1708_parse_auto_config(codec); | 2643 | err = vt1708_parse_auto_config(codec); |
2565 | if (err < 0) { | 2644 | if (err < 0) { |
@@ -2597,7 +2676,6 @@ static int patch_vt1708(struct hda_codec *codec) | |||
2597 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 2676 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
2598 | spec->loopback.amplist = vt1708_loopbacks; | 2677 | spec->loopback.amplist = vt1708_loopbacks; |
2599 | #endif | 2678 | #endif |
2600 | spec->codec = codec; | ||
2601 | INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state); | 2679 | INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state); |
2602 | return 0; | 2680 | return 0; |
2603 | } | 2681 | } |
@@ -3010,9 +3088,9 @@ static int vt1709_parse_auto_config(struct hda_codec *codec) | |||
3010 | spec->input_mux = &spec->private_imux[0]; | 3088 | spec->input_mux = &spec->private_imux[0]; |
3011 | 3089 | ||
3012 | if (spec->hp_mux) | 3090 | if (spec->hp_mux) |
3013 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 3091 | via_hp_build(spec); |
3014 | 3092 | ||
3015 | spec->mixers[spec->num_mixers++] = via_smart51_mixer; | 3093 | via_smart51_build(spec); |
3016 | return 1; | 3094 | return 1; |
3017 | } | 3095 | } |
3018 | 3096 | ||
@@ -3032,12 +3110,10 @@ static int patch_vt1709_10ch(struct hda_codec *codec) | |||
3032 | int err; | 3110 | int err; |
3033 | 3111 | ||
3034 | /* create a codec specific record */ | 3112 | /* create a codec specific record */ |
3035 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 3113 | spec = via_new_spec(codec); |
3036 | if (spec == NULL) | 3114 | if (spec == NULL) |
3037 | return -ENOMEM; | 3115 | return -ENOMEM; |
3038 | 3116 | ||
3039 | codec->spec = spec; | ||
3040 | |||
3041 | err = vt1709_parse_auto_config(codec); | 3117 | err = vt1709_parse_auto_config(codec); |
3042 | if (err < 0) { | 3118 | if (err < 0) { |
3043 | via_free(codec); | 3119 | via_free(codec); |
@@ -3126,12 +3202,10 @@ static int patch_vt1709_6ch(struct hda_codec *codec) | |||
3126 | int err; | 3202 | int err; |
3127 | 3203 | ||
3128 | /* create a codec specific record */ | 3204 | /* create a codec specific record */ |
3129 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 3205 | spec = via_new_spec(codec); |
3130 | if (spec == NULL) | 3206 | if (spec == NULL) |
3131 | return -ENOMEM; | 3207 | return -ENOMEM; |
3132 | 3208 | ||
3133 | codec->spec = spec; | ||
3134 | |||
3135 | err = vt1709_parse_auto_config(codec); | 3209 | err = vt1709_parse_auto_config(codec); |
3136 | if (err < 0) { | 3210 | if (err < 0) { |
3137 | via_free(codec); | 3211 | via_free(codec); |
@@ -3581,9 +3655,9 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec) | |||
3581 | spec->input_mux = &spec->private_imux[0]; | 3655 | spec->input_mux = &spec->private_imux[0]; |
3582 | 3656 | ||
3583 | if (spec->hp_mux) | 3657 | if (spec->hp_mux) |
3584 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 3658 | via_hp_build(spec); |
3585 | 3659 | ||
3586 | spec->mixers[spec->num_mixers++] = via_smart51_mixer; | 3660 | via_smart51_build(spec); |
3587 | return 1; | 3661 | return 1; |
3588 | } | 3662 | } |
3589 | 3663 | ||
@@ -3605,12 +3679,10 @@ static int patch_vt1708B_8ch(struct hda_codec *codec) | |||
3605 | if (get_codec_type(codec) == VT1708BCE) | 3679 | if (get_codec_type(codec) == VT1708BCE) |
3606 | return patch_vt1708S(codec); | 3680 | return patch_vt1708S(codec); |
3607 | /* create a codec specific record */ | 3681 | /* create a codec specific record */ |
3608 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 3682 | spec = via_new_spec(codec); |
3609 | if (spec == NULL) | 3683 | if (spec == NULL) |
3610 | return -ENOMEM; | 3684 | return -ENOMEM; |
3611 | 3685 | ||
3612 | codec->spec = spec; | ||
3613 | |||
3614 | /* automatic parse from the BIOS config */ | 3686 | /* automatic parse from the BIOS config */ |
3615 | err = vt1708B_parse_auto_config(codec); | 3687 | err = vt1708B_parse_auto_config(codec); |
3616 | if (err < 0) { | 3688 | if (err < 0) { |
@@ -3657,12 +3729,10 @@ static int patch_vt1708B_4ch(struct hda_codec *codec) | |||
3657 | int err; | 3729 | int err; |
3658 | 3730 | ||
3659 | /* create a codec specific record */ | 3731 | /* create a codec specific record */ |
3660 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 3732 | spec = via_new_spec(codec); |
3661 | if (spec == NULL) | 3733 | if (spec == NULL) |
3662 | return -ENOMEM; | 3734 | return -ENOMEM; |
3663 | 3735 | ||
3664 | codec->spec = spec; | ||
3665 | |||
3666 | /* automatic parse from the BIOS config */ | 3736 | /* automatic parse from the BIOS config */ |
3667 | err = vt1708B_parse_auto_config(codec); | 3737 | err = vt1708B_parse_auto_config(codec); |
3668 | if (err < 0) { | 3738 | if (err < 0) { |
@@ -4071,9 +4141,9 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) | |||
4071 | spec->input_mux = &spec->private_imux[0]; | 4141 | spec->input_mux = &spec->private_imux[0]; |
4072 | 4142 | ||
4073 | if (spec->hp_mux) | 4143 | if (spec->hp_mux) |
4074 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 4144 | via_hp_build(spec); |
4075 | 4145 | ||
4076 | spec->mixers[spec->num_mixers++] = via_smart51_mixer; | 4146 | via_smart51_build(spec); |
4077 | return 1; | 4147 | return 1; |
4078 | } | 4148 | } |
4079 | 4149 | ||
@@ -4103,12 +4173,10 @@ static int patch_vt1708S(struct hda_codec *codec) | |||
4103 | int err; | 4173 | int err; |
4104 | 4174 | ||
4105 | /* create a codec specific record */ | 4175 | /* create a codec specific record */ |
4106 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4176 | spec = via_new_spec(codec); |
4107 | if (spec == NULL) | 4177 | if (spec == NULL) |
4108 | return -ENOMEM; | 4178 | return -ENOMEM; |
4109 | 4179 | ||
4110 | codec->spec = spec; | ||
4111 | |||
4112 | /* automatic parse from the BIOS config */ | 4180 | /* automatic parse from the BIOS config */ |
4113 | err = vt1708S_parse_auto_config(codec); | 4181 | err = vt1708S_parse_auto_config(codec); |
4114 | if (err < 0) { | 4182 | if (err < 0) { |
@@ -4443,7 +4511,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec) | |||
4443 | spec->input_mux = &spec->private_imux[0]; | 4511 | spec->input_mux = &spec->private_imux[0]; |
4444 | 4512 | ||
4445 | if (spec->hp_mux) | 4513 | if (spec->hp_mux) |
4446 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 4514 | via_hp_build(spec); |
4447 | 4515 | ||
4448 | return 1; | 4516 | return 1; |
4449 | } | 4517 | } |
@@ -4464,12 +4532,10 @@ static int patch_vt1702(struct hda_codec *codec) | |||
4464 | int err; | 4532 | int err; |
4465 | 4533 | ||
4466 | /* create a codec specific record */ | 4534 | /* create a codec specific record */ |
4467 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4535 | spec = via_new_spec(codec); |
4468 | if (spec == NULL) | 4536 | if (spec == NULL) |
4469 | return -ENOMEM; | 4537 | return -ENOMEM; |
4470 | 4538 | ||
4471 | codec->spec = spec; | ||
4472 | |||
4473 | /* automatic parse from the BIOS config */ | 4539 | /* automatic parse from the BIOS config */ |
4474 | err = vt1702_parse_auto_config(codec); | 4540 | err = vt1702_parse_auto_config(codec); |
4475 | if (err < 0) { | 4541 | if (err < 0) { |
@@ -4865,9 +4931,9 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec) | |||
4865 | spec->input_mux = &spec->private_imux[0]; | 4931 | spec->input_mux = &spec->private_imux[0]; |
4866 | 4932 | ||
4867 | if (spec->hp_mux) | 4933 | if (spec->hp_mux) |
4868 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 4934 | via_hp_build(spec); |
4869 | 4935 | ||
4870 | spec->mixers[spec->num_mixers++] = via_smart51_mixer; | 4936 | via_smart51_build(spec); |
4871 | 4937 | ||
4872 | return 1; | 4938 | return 1; |
4873 | } | 4939 | } |
@@ -4888,12 +4954,10 @@ static int patch_vt1718S(struct hda_codec *codec) | |||
4888 | int err; | 4954 | int err; |
4889 | 4955 | ||
4890 | /* create a codec specific record */ | 4956 | /* create a codec specific record */ |
4891 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4957 | spec = via_new_spec(codec); |
4892 | if (spec == NULL) | 4958 | if (spec == NULL) |
4893 | return -ENOMEM; | 4959 | return -ENOMEM; |
4894 | 4960 | ||
4895 | codec->spec = spec; | ||
4896 | |||
4897 | /* automatic parse from the BIOS config */ | 4961 | /* automatic parse from the BIOS config */ |
4898 | err = vt1718S_parse_auto_config(codec); | 4962 | err = vt1718S_parse_auto_config(codec); |
4899 | if (err < 0) { | 4963 | if (err < 0) { |
@@ -5014,6 +5078,7 @@ static struct snd_kcontrol_new vt1716s_dmic_mixer[] = { | |||
5014 | { | 5078 | { |
5015 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 5079 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
5016 | .name = "Digital Mic Capture Switch", | 5080 | .name = "Digital Mic Capture Switch", |
5081 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x26, | ||
5017 | .count = 1, | 5082 | .count = 1, |
5018 | .info = vt1716s_dmic_info, | 5083 | .info = vt1716s_dmic_info, |
5019 | .get = vt1716s_dmic_get, | 5084 | .get = vt1716s_dmic_get, |
@@ -5361,9 +5426,9 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec) | |||
5361 | spec->input_mux = &spec->private_imux[0]; | 5426 | spec->input_mux = &spec->private_imux[0]; |
5362 | 5427 | ||
5363 | if (spec->hp_mux) | 5428 | if (spec->hp_mux) |
5364 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 5429 | via_hp_build(spec); |
5365 | 5430 | ||
5366 | spec->mixers[spec->num_mixers++] = via_smart51_mixer; | 5431 | via_smart51_build(spec); |
5367 | 5432 | ||
5368 | return 1; | 5433 | return 1; |
5369 | } | 5434 | } |
@@ -5384,12 +5449,10 @@ static int patch_vt1716S(struct hda_codec *codec) | |||
5384 | int err; | 5449 | int err; |
5385 | 5450 | ||
5386 | /* create a codec specific record */ | 5451 | /* create a codec specific record */ |
5387 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5452 | spec = via_new_spec(codec); |
5388 | if (spec == NULL) | 5453 | if (spec == NULL) |
5389 | return -ENOMEM; | 5454 | return -ENOMEM; |
5390 | 5455 | ||
5391 | codec->spec = spec; | ||
5392 | |||
5393 | /* automatic parse from the BIOS config */ | 5456 | /* automatic parse from the BIOS config */ |
5394 | err = vt1716S_parse_auto_config(codec); | 5457 | err = vt1716S_parse_auto_config(codec); |
5395 | if (err < 0) { | 5458 | if (err < 0) { |
@@ -5719,7 +5782,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec) | |||
5719 | spec->input_mux = &spec->private_imux[0]; | 5782 | spec->input_mux = &spec->private_imux[0]; |
5720 | 5783 | ||
5721 | if (spec->hp_mux) | 5784 | if (spec->hp_mux) |
5722 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 5785 | via_hp_build(spec); |
5723 | 5786 | ||
5724 | return 1; | 5787 | return 1; |
5725 | } | 5788 | } |
@@ -5741,12 +5804,10 @@ static int patch_vt2002P(struct hda_codec *codec) | |||
5741 | int err; | 5804 | int err; |
5742 | 5805 | ||
5743 | /* create a codec specific record */ | 5806 | /* create a codec specific record */ |
5744 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5807 | spec = via_new_spec(codec); |
5745 | if (spec == NULL) | 5808 | if (spec == NULL) |
5746 | return -ENOMEM; | 5809 | return -ENOMEM; |
5747 | 5810 | ||
5748 | codec->spec = spec; | ||
5749 | |||
5750 | /* automatic parse from the BIOS config */ | 5811 | /* automatic parse from the BIOS config */ |
5751 | err = vt2002P_parse_auto_config(codec); | 5812 | err = vt2002P_parse_auto_config(codec); |
5752 | if (err < 0) { | 5813 | if (err < 0) { |
@@ -6070,7 +6131,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec) | |||
6070 | spec->input_mux = &spec->private_imux[0]; | 6131 | spec->input_mux = &spec->private_imux[0]; |
6071 | 6132 | ||
6072 | if (spec->hp_mux) | 6133 | if (spec->hp_mux) |
6073 | spec->mixers[spec->num_mixers++] = via_hp_mixer; | 6134 | via_hp_build(spec); |
6074 | 6135 | ||
6075 | return 1; | 6136 | return 1; |
6076 | } | 6137 | } |
@@ -6092,12 +6153,10 @@ static int patch_vt1812(struct hda_codec *codec) | |||
6092 | int err; | 6153 | int err; |
6093 | 6154 | ||
6094 | /* create a codec specific record */ | 6155 | /* create a codec specific record */ |
6095 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 6156 | spec = via_new_spec(codec); |
6096 | if (spec == NULL) | 6157 | if (spec == NULL) |
6097 | return -ENOMEM; | 6158 | return -ENOMEM; |
6098 | 6159 | ||
6099 | codec->spec = spec; | ||
6100 | |||
6101 | /* automatic parse from the BIOS config */ | 6160 | /* automatic parse from the BIOS config */ |
6102 | err = vt1812_parse_auto_config(codec); | 6161 | err = vt1812_parse_auto_config(codec); |
6103 | if (err < 0) { | 6162 | if (err < 0) { |