diff options
Diffstat (limited to 'sound/pci/hda/patch_via.c')
-rw-r--r-- | sound/pci/hda/patch_via.c | 58 |
1 files changed, 46 insertions, 12 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 63b0054200a..1371b57c11e 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -159,6 +159,7 @@ struct via_spec { | |||
159 | #endif | 159 | #endif |
160 | }; | 160 | }; |
161 | 161 | ||
162 | static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec); | ||
162 | static struct via_spec * via_new_spec(struct hda_codec *codec) | 163 | static struct via_spec * via_new_spec(struct hda_codec *codec) |
163 | { | 164 | { |
164 | struct via_spec *spec; | 165 | struct via_spec *spec; |
@@ -169,6 +170,10 @@ static struct via_spec * via_new_spec(struct hda_codec *codec) | |||
169 | 170 | ||
170 | codec->spec = spec; | 171 | codec->spec = spec; |
171 | spec->codec = codec; | 172 | spec->codec = codec; |
173 | spec->codec_type = get_codec_type(codec); | ||
174 | /* VT1708BCE & VT1708S are almost same */ | ||
175 | if (spec->codec_type == VT1708BCE) | ||
176 | spec->codec_type = VT1708S; | ||
172 | return spec; | 177 | return spec; |
173 | } | 178 | } |
174 | 179 | ||
@@ -1101,6 +1106,7 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
1101 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1106 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1102 | struct via_spec *spec = codec->spec; | 1107 | struct via_spec *spec = codec->spec; |
1103 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 1108 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
1109 | int ret; | ||
1104 | 1110 | ||
1105 | if (!spec->mux_nids[adc_idx]) | 1111 | if (!spec->mux_nids[adc_idx]) |
1106 | return -EINVAL; | 1112 | return -EINVAL; |
@@ -1109,12 +1115,14 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
1109 | AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0) | 1115 | AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0) |
1110 | snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0, | 1116 | snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0, |
1111 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | 1117 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); |
1112 | /* update jack power state */ | ||
1113 | set_jack_power_state(codec); | ||
1114 | 1118 | ||
1115 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | 1119 | ret = snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, |
1116 | spec->mux_nids[adc_idx], | 1120 | spec->mux_nids[adc_idx], |
1117 | &spec->cur_mux[adc_idx]); | 1121 | &spec->cur_mux[adc_idx]); |
1122 | /* update jack power state */ | ||
1123 | set_jack_power_state(codec); | ||
1124 | |||
1125 | return ret; | ||
1118 | } | 1126 | } |
1119 | 1127 | ||
1120 | static int via_independent_hp_info(struct snd_kcontrol *kcontrol, | 1128 | static int via_independent_hp_info(struct snd_kcontrol *kcontrol, |
@@ -1188,8 +1196,16 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol, | |||
1188 | /* Get Independent Mode index of headphone pin widget */ | 1196 | /* Get Independent Mode index of headphone pin widget */ |
1189 | spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel | 1197 | spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel |
1190 | ? 1 : 0; | 1198 | ? 1 : 0; |
1191 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel); | 1199 | if (spec->codec_type == VT1718S) |
1200 | snd_hda_codec_write(codec, nid, 0, | ||
1201 | AC_VERB_SET_CONNECT_SEL, pinsel ? 2 : 0); | ||
1202 | else | ||
1203 | snd_hda_codec_write(codec, nid, 0, | ||
1204 | AC_VERB_SET_CONNECT_SEL, pinsel); | ||
1192 | 1205 | ||
1206 | if (spec->codec_type == VT1812) | ||
1207 | snd_hda_codec_write(codec, 0x35, 0, | ||
1208 | AC_VERB_SET_CONNECT_SEL, pinsel); | ||
1193 | if (spec->multiout.hp_nid && spec->multiout.hp_nid | 1209 | if (spec->multiout.hp_nid && spec->multiout.hp_nid |
1194 | != spec->multiout.dac_nids[HDA_FRONT]) | 1210 | != spec->multiout.dac_nids[HDA_FRONT]) |
1195 | snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid, | 1211 | snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid, |
@@ -1208,6 +1224,8 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol, | |||
1208 | activate_ctl(codec, "Headphone Playback Switch", | 1224 | activate_ctl(codec, "Headphone Playback Switch", |
1209 | spec->hp_independent_mode); | 1225 | spec->hp_independent_mode); |
1210 | } | 1226 | } |
1227 | /* update jack power state */ | ||
1228 | set_jack_power_state(codec); | ||
1211 | return 0; | 1229 | return 0; |
1212 | } | 1230 | } |
1213 | 1231 | ||
@@ -1248,9 +1266,12 @@ static int via_hp_build(struct hda_codec *codec) | |||
1248 | break; | 1266 | break; |
1249 | } | 1267 | } |
1250 | 1268 | ||
1251 | nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS); | 1269 | if (spec->codec_type != VT1708) { |
1252 | if (nums <= 1) | 1270 | nums = snd_hda_get_connections(codec, nid, |
1253 | return 0; | 1271 | conn, HDA_MAX_CONNECTIONS); |
1272 | if (nums <= 1) | ||
1273 | return 0; | ||
1274 | } | ||
1254 | 1275 | ||
1255 | knew = via_clone_control(spec, &via_hp_mixer[0]); | 1276 | knew = via_clone_control(spec, &via_hp_mixer[0]); |
1256 | if (knew == NULL) | 1277 | if (knew == NULL) |
@@ -1310,6 +1331,11 @@ static void mute_aa_path(struct hda_codec *codec, int mute) | |||
1310 | start_idx = 2; | 1331 | start_idx = 2; |
1311 | end_idx = 4; | 1332 | end_idx = 4; |
1312 | break; | 1333 | break; |
1334 | case VT1718S: | ||
1335 | nid_mixer = 0x21; | ||
1336 | start_idx = 1; | ||
1337 | end_idx = 3; | ||
1338 | break; | ||
1313 | default: | 1339 | default: |
1314 | return; | 1340 | return; |
1315 | } | 1341 | } |
@@ -2185,10 +2211,6 @@ static int via_init(struct hda_codec *codec) | |||
2185 | for (i = 0; i < spec->num_iverbs; i++) | 2211 | for (i = 0; i < spec->num_iverbs; i++) |
2186 | snd_hda_sequence_write(codec, spec->init_verbs[i]); | 2212 | snd_hda_sequence_write(codec, spec->init_verbs[i]); |
2187 | 2213 | ||
2188 | spec->codec_type = get_codec_type(codec); | ||
2189 | if (spec->codec_type == VT1708BCE) | ||
2190 | spec->codec_type = VT1708S; /* VT1708BCE & VT1708S are almost | ||
2191 | same */ | ||
2192 | /* Lydia Add for EAPD enable */ | 2214 | /* Lydia Add for EAPD enable */ |
2193 | if (!spec->dig_in_nid) { /* No Digital In connection */ | 2215 | if (!spec->dig_in_nid) { /* No Digital In connection */ |
2194 | if (spec->dig_in_pin) { | 2216 | if (spec->dig_in_pin) { |
@@ -2438,7 +2460,14 @@ static int vt_auto_create_analog_input_ctls(struct hda_codec *codec, | |||
2438 | else | 2460 | else |
2439 | type_idx = 0; | 2461 | type_idx = 0; |
2440 | label = hda_get_autocfg_input_label(codec, cfg, i); | 2462 | label = hda_get_autocfg_input_label(codec, cfg, i); |
2441 | err = via_new_analog_input(spec, label, type_idx, idx, cap_nid); | 2463 | if (spec->codec_type == VT1708S || |
2464 | spec->codec_type == VT1702 || | ||
2465 | spec->codec_type == VT1716S) | ||
2466 | err = via_new_analog_input(spec, label, type_idx, | ||
2467 | idx+1, cap_nid); | ||
2468 | else | ||
2469 | err = via_new_analog_input(spec, label, type_idx, | ||
2470 | idx, cap_nid); | ||
2442 | if (err < 0) | 2471 | if (err < 0) |
2443 | return err; | 2472 | return err; |
2444 | snd_hda_add_imux_item(imux, label, idx, NULL); | 2473 | snd_hda_add_imux_item(imux, label, idx, NULL); |
@@ -4147,6 +4176,11 @@ static int patch_vt1708S(struct hda_codec *codec) | |||
4147 | spec->stream_name_analog = "VT1708BCE Analog"; | 4176 | spec->stream_name_analog = "VT1708BCE Analog"; |
4148 | spec->stream_name_digital = "VT1708BCE Digital"; | 4177 | spec->stream_name_digital = "VT1708BCE Digital"; |
4149 | } | 4178 | } |
4179 | /* correct names for VT1818S */ | ||
4180 | if (codec->vendor_id == 0x11060440) { | ||
4181 | spec->stream_name_analog = "VT1818S Analog"; | ||
4182 | spec->stream_name_digital = "VT1818S Digital"; | ||
4183 | } | ||
4150 | return 0; | 4184 | return 0; |
4151 | } | 4185 | } |
4152 | 4186 | ||