24 #include <linux/slab.h>
25 #include <linux/pci.h>
26 #include <linux/module.h>
112 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->
id);
114 ucontrol->
value.enumerated.item[0] = spec->
cur_mux[adc_idx];
122 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->
id);
142 static const char *
const ad_slave_pfxs[] = {
143 "Front",
"Surround",
"Center",
"LFE",
"Side",
144 "Headphone",
"Mono",
"Speaker",
"IEC958",
148 static const char *
const ad1988_6stack_fp_slave_pfxs[] = {
149 "Front",
"Surround",
"Center",
"LFE",
"Side",
"IEC958",
153 static void ad198x_free_kctls(
struct hda_codec *codec);
155 #ifdef CONFIG_SND_HDA_INPUT_BEEP
169 #define set_beep_amp(spec, nid, idx, dir) \
170 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir))
172 #define set_beep_amp(spec, nid, idx, dir)
175 static int ad198x_build_controls(
struct hda_codec *codec)
206 #ifdef CONFIG_SND_HDA_INPUT_BEEP
209 knew = spec->
analog_beep ? ad_beep2_mixer : ad_beep_mixer;
210 for ( ; knew->
name; knew++) {
225 unsigned int vmaster_tlv[4];
247 ad198x_free_kctls(codec);
253 for (i = 0; kctl && i < kctl->
count; i++) {
285 ctl->
vd[0].access |= active ? 0 :
288 ctl->
vd[0].access |= active ?
295 static void set_stream_active(
struct hda_codec *codec,
bool active)
305 static int ad1988_independent_hp_info(
struct snd_kcontrol *kcontrol,
308 static const char *
const texts[] = {
"OFF",
"ON",
NULL};
320 static int ad1988_independent_hp_get(
struct snd_kcontrol *kcontrol,
329 static int ad1988_independent_hp_put(
struct snd_kcontrol *kcontrol,
334 unsigned int select = ucontrol->
value.enumerated.item[0];
355 set_stream_active(codec,
true);
359 set_stream_active(codec,
false);
365 static int ad198x_playback_pcm_prepare(
struct hda_pcm_stream *hinfo,
367 unsigned int stream_tag,
376 static int ad198x_playback_pcm_cleanup(
struct hda_pcm_stream *hinfo,
384 static int ad198x_playback_pcm_close(
struct hda_pcm_stream *hinfo,
388 set_stream_active(codec,
false);
392 static int ad1988_alt_playback_pcm_open(
struct hda_pcm_stream *hinfo,
399 set_stream_active(codec,
true);
403 static int ad1988_alt_playback_pcm_close(
struct hda_pcm_stream *hinfo,
407 set_stream_active(codec,
false);
411 static const struct hda_pcm_stream ad198x_pcm_analog_alt_playback = {
416 .open = ad1988_alt_playback_pcm_open,
417 .close = ad1988_alt_playback_pcm_close
424 static int ad198x_dig_playback_pcm_open(
struct hda_pcm_stream *hinfo,
432 static int ad198x_dig_playback_pcm_close(
struct hda_pcm_stream *hinfo,
440 static int ad198x_dig_playback_pcm_prepare(
struct hda_pcm_stream *hinfo,
442 unsigned int stream_tag,
451 static int ad198x_dig_playback_pcm_cleanup(
struct hda_pcm_stream *hinfo,
462 static int ad198x_capture_pcm_prepare(
struct hda_pcm_stream *hinfo,
464 unsigned int stream_tag,
470 stream_tag, 0, format);
474 static int ad198x_capture_pcm_cleanup(
struct hda_pcm_stream *hinfo,
491 .open = ad198x_playback_pcm_open,
492 .prepare = ad198x_playback_pcm_prepare,
493 .cleanup = ad198x_playback_pcm_cleanup,
494 .close = ad198x_playback_pcm_close
504 .prepare = ad198x_capture_pcm_prepare,
505 .cleanup = ad198x_capture_pcm_cleanup
509 static const struct hda_pcm_stream ad198x_pcm_digital_playback = {
515 .open = ad198x_dig_playback_pcm_open,
516 .close = ad198x_dig_playback_pcm_close,
517 .prepare = ad198x_dig_playback_pcm_prepare,
518 .cleanup = ad198x_dig_playback_pcm_cleanup
529 static int ad198x_build_pcms(
struct hda_codec *codec)
537 info->
name =
"AD198x Analog";
549 info->
name =
"AD198x Digital";
562 info->
name =
"AD198x Headphone";
573 static void ad198x_free_kctls(
struct hda_codec *codec)
577 if (spec->
kctls.list) {
580 for (i = 0; i < spec->
kctls.used; i++)
598 static void ad198x_power_eapd(
struct hda_codec *codec)
614 ad198x_power_eapd_write(codec, 0x12, 0x11);
618 ad198x_power_eapd_write(codec, 0x05, 0x06);
621 ad198x_power_eapd_write(codec, 0x1b, 0x1a);
626 static void ad198x_shutup(
struct hda_codec *codec)
629 ad198x_power_eapd(codec);
632 static void ad198x_free(
struct hda_codec *codec)
639 ad198x_shutup(codec);
640 ad198x_free_kctls(codec);
646 static int ad198x_suspend(
struct hda_codec *codec)
648 ad198x_shutup(codec);
654 .build_controls = ad198x_build_controls,
655 .build_pcms = ad198x_build_pcms,
659 .check_power_status = ad198x_check_power_status,
660 .suspend = ad198x_suspend,
662 .reboot_notify = ad198x_shutup,
670 #define ad198x_eapd_info snd_ctl_boolean_mono_info
672 static int ad198x_eapd_get(
struct snd_kcontrol *kcontrol,
684 static int ad198x_eapd_put(
struct snd_kcontrol *kcontrol,
691 eapd = !!ucontrol->
value.integer.value[0];
703 static int ad198x_ch_mode_info(
struct snd_kcontrol *kcontrol,
705 static int ad198x_ch_mode_get(
struct snd_kcontrol *kcontrol,
707 static int ad198x_ch_mode_put(
struct snd_kcontrol *kcontrol,
715 #define AD1986A_SPDIF_OUT 0x02
716 #define AD1986A_FRONT_DAC 0x03
717 #define AD1986A_SURR_DAC 0x04
718 #define AD1986A_CLFE_DAC 0x05
719 #define AD1986A_ADC 0x06
721 static const hda_nid_t ad1986a_dac_nids[3] = {
725 static const hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 };
768 HDA_BIND_VOL(
"PCM Playback Volume", &ad1986a_bind_pcm_vol),
769 HDA_BIND_SW(
"PCM Playback Switch", &ad1986a_bind_pcm_sw),
795 .name =
"Capture Source",
796 .info = ad198x_mux_enum_info,
797 .get = ad198x_mux_enum_get,
798 .put = ad198x_mux_enum_put,
808 .name =
"Channel Mode",
809 .info = ad198x_ch_mode_info,
810 .get = ad198x_ch_mode_get,
811 .put = ad198x_ch_mode_put,
820 static const struct hda_bind_ctls ad1986a_laptop_master_vol = {
829 static const struct hda_bind_ctls ad1986a_laptop_master_sw = {
841 HDA_BIND_VOL(
"Master Playback Volume", &ad1986a_laptop_master_vol),
842 HDA_BIND_SW(
"Master Playback Switch", &ad1986a_laptop_master_sw),
859 .name =
"Capture Source",
860 .info = ad198x_mux_enum_info,
861 .get = ad198x_mux_enum_get,
862 .put = ad198x_mux_enum_put,
869 static const struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
873 {
"Internal Mic", 0x4 },
878 static const struct hda_input_mux ad1986a_automic_capture_source = {
887 HDA_BIND_VOL(
"Master Playback Volume", &ad1986a_laptop_master_vol),
888 HDA_BIND_SW(
"Master Playback Switch", &ad1986a_laptop_master_sw),
902 .name =
"Capture Source",
903 .info = ad198x_mux_enum_info,
904 .get = ad198x_mux_enum_get,
905 .put = ad198x_mux_enum_put,
909 .name =
"External Amplifier",
912 .get = ad198x_eapd_get,
913 .put = ad198x_eapd_put,
914 .private_value = 0x1b,
926 static void ad1986a_automic(
struct hda_codec *codec)
928 unsigned int present;
935 #define AD1986A_MIC_EVENT 0x36
937 static void ad1986a_automic_unsol_event(
struct hda_codec *codec,
942 ad1986a_automic(codec);
945 static int ad1986a_automic_init(
struct hda_codec *codec)
948 ad1986a_automic(codec);
954 static void ad1986a_update_hp(
struct hda_codec *codec)
968 static void ad1986a_hp_automute(
struct hda_codec *codec)
975 ad1986a_update_hp(codec);
978 #define AD1986A_HP_EVENT 0x37
980 static void ad1986a_hp_unsol_event(
struct hda_codec *codec,
unsigned int res)
984 ad1986a_hp_automute(codec);
987 static int ad1986a_hp_init(
struct hda_codec *codec)
990 ad1986a_hp_automute(codec);
995 static int ad1986a_hp_master_sw_put(
struct snd_kcontrol *kcontrol,
999 long *valp = ucontrol->
value.integer.value;
1009 ad1986a_update_hp(codec);
1014 HDA_BIND_VOL(
"Master Playback Volume", &ad1986a_laptop_master_vol),
1017 .name =
"Master Playback Switch",
1021 .put = ad1986a_hp_master_sw_put,
1031 static const struct hda_verb ad1986a_init_verbs[] = {
1086 static const struct hda_verb ad1986a_ch2_init[] = {
1098 static const struct hda_verb ad1986a_ch4_init[] = {
1108 static const struct hda_verb ad1986a_ch6_init[] = {
1119 { 2, ad1986a_ch2_init },
1120 { 4, ad1986a_ch4_init },
1121 { 6, ad1986a_ch6_init },
1125 static const struct hda_verb ad1986a_eapd_init_verbs[] = {
1130 static const struct hda_verb ad1986a_automic_verbs[] = {
1140 static const struct hda_verb ad1986a_ultra_init[] = {
1151 static const struct hda_verb ad1986a_hp_init_verbs[] = {
1156 static void ad1986a_samsung_p50_unsol_event(
struct hda_codec *codec,
1159 switch (res >> 26) {
1161 ad1986a_hp_automute(codec);
1164 ad1986a_automic(codec);
1169 static int ad1986a_samsung_p50_init(
struct hda_codec *codec)
1172 ad1986a_hp_automute(codec);
1173 ad1986a_automic(codec);
1202 static const struct snd_pci_quirk ad1986a_cfg_tbl[] = {
1219 SND_PCI_QUIRK(0x1179, 0xff40,
"Toshiba Satellite L40-10Q",
AD1986A_3STACK),
1224 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000,
"Samsung",
AD1986A_SAMSUNG),
1234 static const struct hda_amp_list ad1986a_loopbacks[] = {
1250 static int patch_ad1986a(
struct hda_codec *codec)
1253 int err, board_config;
1270 spec->
multiout.dac_nids = ad1986a_dac_nids;
1275 spec->
input_mux = &ad1986a_capture_source;
1277 spec->
mixers[0] = ad1986a_mixers;
1281 spec->loopback.amplist = ad1986a_loopbacks;
1292 switch (board_config) {
1295 spec->
mixers[1] = ad1986a_3st_mixers;
1305 spec->
mixers[0] = ad1986a_laptop_mixers;
1308 spec->
multiout.dac_nids = ad1986a_laptop_dac_nids;
1312 spec->
mixers[0] = ad1986a_laptop_master_mixers;
1313 spec->
mixers[1] = ad1986a_laptop_eapd_mixers;
1314 spec->
mixers[2] = ad1986a_laptop_intmic_mixers;
1316 spec->
init_verbs[1] = ad1986a_eapd_init_verbs;
1319 spec->
multiout.dac_nids = ad1986a_laptop_dac_nids;
1320 if (!is_jack_available(codec, 0x25))
1322 spec->
input_mux = &ad1986a_laptop_eapd_capture_source;
1326 spec->
mixers[0] = ad1986a_laptop_master_mixers;
1327 spec->
mixers[1] = ad1986a_laptop_eapd_mixers;
1329 spec->
init_verbs[1] = ad1986a_eapd_init_verbs;
1333 spec->
multiout.dac_nids = ad1986a_laptop_dac_nids;
1334 if (!is_jack_available(codec, 0x25))
1336 spec->
input_mux = &ad1986a_automic_capture_source;
1337 codec->
patch_ops.unsol_event = ad1986a_automic_unsol_event;
1338 codec->
patch_ops.init = ad1986a_automic_init;
1342 spec->
mixers[0] = ad1986a_automute_master_mixers;
1343 spec->
mixers[1] = ad1986a_laptop_eapd_mixers;
1345 spec->
init_verbs[1] = ad1986a_eapd_init_verbs;
1350 spec->
multiout.dac_nids = ad1986a_laptop_dac_nids;
1351 if (!is_jack_available(codec, 0x25))
1353 spec->
input_mux = &ad1986a_automic_capture_source;
1354 codec->
patch_ops.unsol_event = ad1986a_samsung_p50_unsol_event;
1355 codec->
patch_ops.init = ad1986a_samsung_p50_init;
1359 spec->
mixers[0] = ad1986a_automute_master_mixers;
1360 spec->
mixers[1] = ad1986a_laptop_eapd_mixers;
1361 spec->
mixers[2] = ad1986a_laptop_intmic_mixers;
1363 spec->
init_verbs[1] = ad1986a_eapd_init_verbs;
1367 spec->
multiout.dac_nids = ad1986a_laptop_dac_nids;
1368 if (!is_jack_available(codec, 0x25))
1370 spec->
input_mux = &ad1986a_laptop_eapd_capture_source;
1371 codec->
patch_ops.unsol_event = ad1986a_hp_unsol_event;
1372 codec->
patch_ops.init = ad1986a_hp_init;
1379 spec->
mixers[0] = ad1986a_laptop_eapd_mixers;
1384 spec->
multiout.dac_nids = ad1986a_laptop_dac_nids;
1395 spec->
multiout.no_share_stream = 1;
1407 #define AD1983_SPDIF_OUT 0x02
1408 #define AD1983_DAC 0x03
1409 #define AD1983_ADC 0x04
1413 static const hda_nid_t ad1983_capsrc_nids[1] = { 0x15 };
1421 {
"Mix Mono", 0x3 },
1430 static const char *
const texts[] = {
"PCM",
"ADC" };
1455 if (ucontrol->
value.enumerated.item[0] > 1)
1485 .name =
"Capture Source",
1486 .info = ad198x_mux_enum_info,
1487 .get = ad198x_mux_enum_get,
1488 .put = ad198x_mux_enum_put,
1493 .info = ad1983_spdif_route_info,
1494 .get = ad1983_spdif_route_get,
1495 .put = ad1983_spdif_route_put,
1500 static const struct hda_verb ad1983_init_verbs[] = {
1540 static const struct hda_amp_list ad1983_loopbacks[] = {
1547 static int patch_ad1983(
struct hda_codec *codec)
1567 spec->
multiout.dac_nids = ad1983_dac_nids;
1572 spec->
input_mux = &ad1983_capture_source;
1574 spec->
mixers[0] = ad1983_mixers;
1579 spec->loopback.amplist = ad1983_loopbacks;
1596 #define AD1981_SPDIF_OUT 0x02
1597 #define AD1981_DAC 0x03
1598 #define AD1981_ADC 0x04
1602 static const hda_nid_t ad1981_capsrc_nids[1] = { 0x15 };
1608 {
"Front Mic", 0x0 },
1611 {
"Mix Mono", 0x3 },
1643 .name =
"Capture Source",
1644 .info = ad198x_mux_enum_info,
1645 .get = ad198x_mux_enum_get,
1646 .put = ad198x_mux_enum_put,
1652 .info = ad1983_spdif_route_info,
1653 .get = ad1983_spdif_route_get,
1654 .put = ad1983_spdif_route_put,
1659 static const struct hda_verb ad1981_init_verbs[] = {
1707 static const struct hda_amp_list ad1981_loopbacks[] = {
1724 #define AD1981_HP_EVENT 0x37
1725 #define AD1981_MIC_EVENT 0x38
1727 static const struct hda_verb ad1981_hp_init_verbs[] = {
1736 static int ad1981_hp_master_sw_put(
struct snd_kcontrol *kcontrol,
1742 if (! ad198x_eapd_put(kcontrol, ucontrol))
1754 static const struct hda_bind_ctls ad1981_hp_bind_master_vol = {
1764 static void ad1981_hp_automute(
struct hda_codec *codec)
1766 unsigned int present;
1774 static void ad1981_hp_automic(
struct hda_codec *codec)
1776 static const struct hda_verb mic_jack_on[] = {
1781 static const struct hda_verb mic_jack_off[] = {
1786 unsigned int present;
1796 static void ad1981_hp_unsol_event(
struct hda_codec *codec,
1802 ad1981_hp_automute(codec);
1805 ad1981_hp_automic(codec);
1810 static const struct hda_input_mux ad1981_hp_capture_source = {
1814 {
"Dock Mic", 0x1 },
1820 HDA_BIND_VOL(
"Master Playback Volume", &ad1981_hp_bind_master_vol),
1824 .name =
"Master Playback Switch",
1826 .get = ad198x_eapd_get,
1827 .put = ad1981_hp_master_sw_put,
1828 .private_value = 0x05,
1852 .name =
"Capture Source",
1853 .info = ad198x_mux_enum_info,
1854 .get = ad198x_mux_enum_get,
1855 .put = ad198x_mux_enum_put,
1861 static int ad1981_hp_init(
struct hda_codec *codec)
1864 ad1981_hp_automute(codec);
1865 ad1981_hp_automic(codec);
1870 static const struct hda_verb ad1981_toshiba_init_verbs[] = {
1899 .name =
"Capture Source",
1900 .info = ad198x_mux_enum_info,
1901 .get = ad198x_mux_enum_get,
1902 .put = ad198x_mux_enum_put,
1908 .info = ad1983_spdif_route_info,
1909 .get = ad1983_spdif_route_get,
1910 .put = ad1983_spdif_route_put,
1915 static const struct hda_input_mux ad1981_thinkpad_capture_source = {
1940 static const struct snd_pci_quirk ad1981_cfg_tbl[] = {
1944 SND_PCI_QUIRK_VENDOR(0x103c,
"HP nx",
AD1981_HP),
1949 SND_PCI_QUIRK(0x30b0, 0x103c,
"HP nx6320",
AD1981_HP),
1953 static int patch_ad1981(
struct hda_codec *codec)
1956 int err, board_config;
1973 spec->
multiout.dac_nids = ad1981_dac_nids;
1978 spec->
input_mux = &ad1981_capture_source;
1980 spec->
mixers[0] = ad1981_mixers;
1985 spec->loopback.amplist = ad1981_loopbacks;
1995 switch (board_config) {
1997 spec->
mixers[0] = ad1981_hp_mixers;
2000 if (!is_jack_available(codec, 0x0a))
2002 spec->
input_mux = &ad1981_hp_capture_source;
2005 codec->
patch_ops.unsol_event = ad1981_hp_unsol_event;
2016 spec->
mixers[0] = ad1981_thinkpad_mixers;
2017 spec->
input_mux = &ad1981_thinkpad_capture_source;
2028 spec->
mixers[0] = ad1981_hp_mixers;
2029 spec->
mixers[1] = ad1981_toshiba_mixers;
2031 spec->
init_verbs[1] = ad1981_toshiba_init_verbs;
2033 spec->
input_mux = &ad1981_hp_capture_source;
2035 codec->
patch_ops.unsol_event = ad1981_hp_unsol_event;
2145 #define AD1988A_REV2 0x100200
2147 #define is_rev2(codec) \
2148 ((codec)->vendor_id == 0x11d41988 && \
2149 (codec)->revision_id == AD1988A_REV2)
2155 static const hda_nid_t ad1988_6stack_dac_nids[4] = {
2156 0x04, 0x06, 0x05, 0x0a
2159 static const hda_nid_t ad1988_3stack_dac_nids[3] = {
2164 static const hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
2165 0x04, 0x05, 0x0a, 0x06
2168 static const hda_nid_t ad1988_alt_dac_nid[1] = {
2172 static const hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
2176 static const hda_nid_t ad1988_adc_nids[3] = {
2180 static const hda_nid_t ad1988_capsrc_nids[3] = {
2184 #define AD1988_SPDIF_OUT 0x02
2185 #define AD1988_SPDIF_OUT_HDMI 0x0b
2186 #define AD1988_SPDIF_IN 0x07
2188 static const hda_nid_t ad1989b_slave_dig_outs[] = {
2192 static const struct hda_input_mux ad1988_6stack_capture_source = {
2195 {
"Front Mic", 0x1 },
2203 static const struct hda_input_mux ad1988_laptop_capture_source = {
2206 {
"Mic/Line", 0x1 },
2214 static int ad198x_ch_mode_info(
struct snd_kcontrol *kcontrol,
2223 static int ad198x_ch_mode_get(
struct snd_kcontrol *kcontrol,
2232 static int ad198x_ch_mode_put(
struct snd_kcontrol *kcontrol,
2248 .name =
"Independent HP",
2249 .info = ad1988_independent_hp_info,
2250 .get = ad1988_independent_hp_get,
2251 .put = ad1988_independent_hp_put,
2344 .name =
"Channel Mode",
2345 .info = ad198x_ch_mode_info,
2346 .get = ad198x_ch_mode_get,
2347 .put = ad198x_ch_mode_put,
2374 .name =
"External Amplifier",
2377 .get = ad198x_eapd_get,
2378 .put = ad198x_eapd_put,
2379 .private_value = 0x12,
2399 .name =
"Input Source",
2401 .info = ad198x_mux_enum_info,
2402 .get = ad198x_mux_enum_get,
2403 .put = ad198x_mux_enum_put,
2408 static int ad1988_spdif_playback_source_info(
struct snd_kcontrol *kcontrol,
2411 static const char *
const texts[] = {
2412 "PCM",
"ADC1",
"ADC2",
"ADC3"
2423 static int ad1988_spdif_playback_source_get(
struct snd_kcontrol *kcontrol,
2432 ucontrol->
value.enumerated.item[0] = 0;
2440 ucontrol->
value.enumerated.item[0] =
sel;
2445 static int ad1988_spdif_playback_source_put(
struct snd_kcontrol *kcontrol,
2452 val = ucontrol->
value.enumerated.item[0];
2459 change = sel & 0x80;
2472 change = sel & 0x80;
2483 change |= sel !=
val;
2496 .name =
"IEC958 Playback Source",
2498 .info = ad1988_spdif_playback_source_info,
2499 .get = ad1988_spdif_playback_source_get,
2500 .put = ad1988_spdif_playback_source_put,
2523 static const struct hda_verb ad1988_6stack_init_verbs[] = {
2583 static const struct hda_verb ad1988_6stack_fp_init_verbs[] = {
2596 static const struct hda_verb ad1988_capture_init_verbs[] = {
2614 static const struct hda_verb ad1988_spdif_init_verbs[] = {
2626 static const struct hda_verb ad1988_spdif_in_init_verbs[] = {
2633 static const struct hda_verb ad1989_spdif_init_verbs[] = {
2646 static const struct hda_verb ad1988_3stack_ch2_init[] = {
2656 static const struct hda_verb ad1988_3stack_ch6_init[] = {
2667 { 2, ad1988_3stack_ch2_init },
2668 { 6, ad1988_3stack_ch6_init },
2671 static const struct hda_verb ad1988_3stack_init_verbs[] = {
2731 static const struct hda_verb ad1988_laptop_hp_on[] = {
2737 static const struct hda_verb ad1988_laptop_hp_off[] = {
2744 #define AD1988_HP_EVENT 0x01
2746 static const struct hda_verb ad1988_laptop_init_verbs[] = {
2799 static void ad1988_laptop_unsol_event(
struct hda_codec *codec,
unsigned int res)
2810 static const struct hda_amp_list ad1988_loopbacks[] = {
2835 static int add_control(
struct ad198x_spec *spec,
int type,
const char *name,
2840 snd_array_init(&spec->
kctls,
sizeof(*knew), 32);
2844 *knew = ad1988_control_templates[
type];
2854 #define AD1988_PIN_CD_NID 0x18
2855 #define AD1988_PIN_BEEP_NID 0x10
2857 static const hda_nid_t ad1988_mixer_nids[8] = {
2859 0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28
2864 static const hda_nid_t idx_to_dac[8] = {
2866 0x03, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a
2868 static const hda_nid_t idx_to_dac_rev2[8] = {
2870 0x03, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06
2873 return idx_to_dac_rev2[
idx];
2875 return idx_to_dac[
idx];
2878 static const hda_nid_t ad1988_boost_nids[8] = {
2879 0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0
2882 static int ad1988_pin_idx(
hda_nid_t nid)
2884 static const hda_nid_t ad1988_io_pins[8] = {
2885 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25
2888 for (i = 0; i <
ARRAY_SIZE(ad1988_io_pins); i++)
2889 if (ad1988_io_pins[i] == nid)
2894 static int ad1988_pin_to_loopback_idx(
hda_nid_t nid)
2896 static const int loopback_idx[8] = {
2897 2, 0, 1, 3, 4, 5, 1, 4
2903 return loopback_idx[ad1988_pin_idx(nid)];
2907 static int ad1988_pin_to_adc_idx(
hda_nid_t nid)
2909 static const int adc_idx[8] = {
2910 0, 1, 2, 8, 4, 3, 6, 7
2916 return adc_idx[ad1988_pin_idx(nid)];
2921 static int ad1988_auto_fill_dac_nids(
struct hda_codec *codec,
2939 static int ad1988_auto_create_multi_out_ctls(
struct ad198x_spec *spec,
2943 static const char *
const chname[4] = {
2944 "Front",
"Surround",
NULL ,
"Side"
2953 nid = ad1988_mixer_nids[ad1988_pin_idx(cfg->
line_out_pins[i])];
2957 "Center Playback Volume",
2962 "LFE Playback Volume",
2967 "Center Playback Switch",
2972 "LFE Playback Switch",
2977 sprintf(name,
"%s Playback Volume", chname[i]);
2982 sprintf(name,
"%s Playback Switch", chname[i]);
3004 idx = ad1988_pin_idx(pin);
3005 nid = ad1988_idx_to_dac(codec, idx);
3007 for (i = 0; i < spec->
autocfg.line_outs; i++) {
3009 hda_nid_t dac = ad1988_idx_to_dac(codec, ad1988_pin_idx(pin));
3013 if (i >= spec->
autocfg.line_outs) {
3018 spec->
multiout.extra_out_nid[0] = nid;
3020 sprintf(name,
"%s Playback Volume", pfx);
3026 nid = ad1988_mixer_nids[
idx];
3027 sprintf(name,
"%s Playback Switch", pfx);
3036 const char *ctlname,
int ctlidx,
int boost)
3041 sprintf(name,
"%s Playback Volume", ctlname);
3042 idx = ad1988_pin_to_loopback_idx(pin);
3046 sprintf(name,
"%s Playback Switch", ctlname);
3052 idx = ad1988_pin_idx(pin);
3053 bnid = ad1988_boost_nids[
idx];
3055 sprintf(name,
"%s Boost Volume", ctlname);
3065 static int ad1988_auto_create_analog_input_ctls(
struct hda_codec *codec,
3077 ad1988_pin_to_adc_idx(cfg->
inputs[i].pin),
3079 err = new_analog_input(spec, cfg->
inputs[i].pin,
3088 "Analog Mix Playback Volume",
3092 "Analog Mix Playback Switch",
3099 static void ad1988_auto_set_output_and_unmute(
struct hda_codec *codec,
3104 snd_hda_set_pin_ctl(codec, nid, pin_type);
3125 static void ad1988_auto_init_multi_out(
struct hda_codec *codec)
3130 for (i = 0; i < spec->
autocfg.line_outs; i++) {
3132 ad1988_auto_set_output_and_unmute(codec, nid,
PIN_OUT, i);
3136 static void ad1988_auto_init_extra_out(
struct hda_codec *codec)
3141 pin = spec->
autocfg.speaker_pins[0];
3143 ad1988_auto_set_output_and_unmute(codec, pin,
PIN_OUT, 0);
3144 pin = spec->
autocfg.hp_pins[0];
3146 ad1988_auto_set_output_and_unmute(codec, pin,
PIN_HP, 0);
3149 static void ad1988_auto_init_analog_input(
struct hda_codec *codec)
3157 int type = cfg->
inputs[
i].type;
3170 snd_hda_set_pin_ctl(codec, nid, val);
3174 idx = ad1988_pin_idx(nid);
3175 if (ad1988_boost_nids[idx])
3184 static int ad1988_parse_auto_config(
struct hda_codec *codec)
3191 if ((err = ad1988_auto_fill_dac_nids(codec, &spec->
autocfg)) < 0)
3193 if (! spec->
autocfg.line_outs)
3195 if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->
autocfg)) < 0 ||
3196 (err = ad1988_auto_create_extra_out(codec,
3197 spec->
autocfg.speaker_pins[0],
3199 (err = ad1988_auto_create_extra_out(codec, spec->
autocfg.hp_pins[0],
3200 "Headphone")) < 0 ||
3201 (err = ad1988_auto_create_analog_input_ctls(codec, &spec->
autocfg)) < 0)
3211 if (spec->
kctls.list)
3222 static int ad1988_auto_init(
struct hda_codec *codec)
3225 ad1988_auto_init_multi_out(codec);
3226 ad1988_auto_init_extra_out(codec);
3227 ad1988_auto_init_analog_input(codec);
3244 static const struct snd_pci_quirk ad1988_cfg_tbl[] = {
3253 static int patch_ad1988(
struct hda_codec *codec)
3256 int err, board_config;
3268 ad1988_models, ad1988_cfg_tbl);
3269 if (board_config < 0) {
3277 err = ad1988_parse_auto_config(codec);
3282 printk(
KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using 6-stack mode...\n");
3295 spec->
multiout.hp_nid = ad1988_alt_dac_nid[0];
3296 switch (board_config) {
3302 spec->
multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
3304 spec->
multiout.dac_nids = ad1988_6stack_dac_nids;
3305 spec->
input_mux = &ad1988_6stack_capture_source;
3308 spec->
mixers[0] = ad1988_6stack_mixers1_rev2;
3310 spec->
mixers[0] = ad1988_6stack_mixers1;
3311 spec->
mixers[1] = ad1988_6stack_mixers2;
3313 spec->
init_verbs[0] = ad1988_6stack_init_verbs;
3324 spec->
multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
3326 spec->
multiout.dac_nids = ad1988_3stack_dac_nids;
3327 spec->
input_mux = &ad1988_6stack_capture_source;
3332 spec->
mixers[0] = ad1988_3stack_mixers1_rev2;
3334 spec->
mixers[0] = ad1988_3stack_mixers1;
3335 spec->
mixers[1] = ad1988_3stack_mixers2;
3337 spec->
init_verbs[0] = ad1988_3stack_init_verbs;
3345 spec->
multiout.dac_nids = ad1988_3stack_dac_nids;
3346 spec->
input_mux = &ad1988_laptop_capture_source;
3348 spec->
mixers[0] = ad1988_laptop_mixers;
3351 spec->
init_verbs[0] = ad1988_laptop_init_verbs;
3357 if (spec->
autocfg.hp_pins[0]) {
3359 spec->
slave_vols = ad1988_6stack_fp_slave_pfxs;
3360 spec->
slave_sws = ad1988_6stack_fp_slave_pfxs;
3363 &ad198x_pcm_analog_alt_playback;
3374 ad1989_spdif_out_mixers;
3376 ad1989_spdif_init_verbs;
3380 ad1988_spdif_out_mixers;
3382 ad1988_spdif_init_verbs;
3388 ad1988_spdif_in_init_verbs;
3392 switch (board_config) {
3394 codec->
patch_ops.init = ad1988_auto_init;
3398 codec->
patch_ops.unsol_event = ad1988_laptop_unsol_event;
3402 spec->loopback.amplist = ad1988_loopbacks;
3431 static const hda_nid_t ad1884_dac_nids[1] = {
3435 static const hda_nid_t ad1884_adc_nids[2] = {
3439 static const hda_nid_t ad1884_capsrc_nids[2] = {
3443 #define AD1884_SPDIF_OUT 0x02
3448 {
"Front Mic", 0x0 },
3480 .name =
"Input Source",
3482 .info = ad198x_mux_enum_info,
3483 .get = ad198x_mux_enum_get,
3484 .put = ad198x_mux_enum_put,
3492 .info = ad1983_spdif_route_info,
3493 .get = ad1983_spdif_route_get,
3494 .put = ad1983_spdif_route_put,
3512 static const struct hda_verb ad1884_init_verbs[] = {
3558 static const struct hda_amp_list ad1884_loopbacks[] = {
3567 static const char *
const ad1884_slave_vols[] = {
3568 "PCM",
"Mic",
"Mono",
"Front Mic",
"Mic",
"CD",
3569 "Internal Mic",
"Dock Mic",
"IEC958",
3573 static int patch_ad1884(
struct hda_codec *codec)
3593 spec->
multiout.dac_nids = ad1884_dac_nids;
3598 spec->
input_mux = &ad1884_capture_source;
3600 spec->
mixers[0] = ad1884_base_mixers;
3605 spec->loopback.amplist = ad1884_loopbacks;
3624 static const struct hda_input_mux ad1984_thinkpad_capture_source = {
3628 {
"Internal Mic", 0x1 },
3630 {
"Dock Mic", 0x4 },
3638 static const struct hda_input_mux ad1984_dell_desktop_capture_source = {
3641 {
"Front Mic", 0x0 },
3674 .name =
"Input Source",
3676 .info = ad198x_mux_enum_info,
3677 .get = ad198x_mux_enum_get,
3678 .put = ad198x_mux_enum_put,
3686 .info = ad1983_spdif_route_info,
3687 .get = ad1983_spdif_route_get,
3688 .put = ad1983_spdif_route_put,
3694 static const struct hda_verb ad1984_thinkpad_init_verbs[] = {
3734 .name =
"Input Source",
3736 .info = ad198x_mux_enum_info,
3737 .get = ad198x_mux_enum_get,
3738 .put = ad198x_mux_enum_put,
3746 unsigned int stream_tag,
3751 stream_tag, 0, format);
3769 .prepare = ad1984_pcm_dmic_prepare,
3770 .cleanup = ad1984_pcm_dmic_cleanup
3774 static int ad1984_build_pcms(
struct hda_codec *codec)
3780 err = ad198x_build_pcms(codec);
3786 info->
name =
"AD1984 Digital Mic";
3805 static const struct snd_pci_quirk ad1984_cfg_tbl[] = {
3813 static int patch_ad1984(
struct hda_codec *codec)
3816 int board_config,
err;
3818 err = patch_ad1884(codec);
3823 ad1984_models, ad1984_cfg_tbl);
3824 switch (board_config) {
3828 codec->
patch_ops.build_pcms = ad1984_build_pcms;
3837 spec->
input_mux = &ad1984_thinkpad_capture_source;
3838 spec->
mixers[0] = ad1984_thinkpad_mixers;
3844 spec->
input_mux = &ad1984_dell_desktop_capture_source;
3845 spec->
mixers[0] = ad1984_dell_desktop_mixers;
3870 static const hda_nid_t ad1884a_dac_nids[1] = {
3874 #define ad1884a_adc_nids ad1884_adc_nids
3875 #define ad1884a_capsrc_nids ad1884_capsrc_nids
3877 #define AD1884A_SPDIF_OUT 0x02
3879 static const struct hda_input_mux ad1884a_capture_source = {
3882 {
"Front Mic", 0x0 },
3920 .name =
"Input Source",
3922 .info = ad198x_mux_enum_info,
3923 .get = ad198x_mux_enum_get,
3924 .put = ad198x_mux_enum_put,
3932 .info = ad1983_spdif_route_info,
3933 .get = ad1983_spdif_route_get,
3934 .put = ad1983_spdif_route_put,
3942 static const struct hda_verb ad1884a_init_verbs[] = {
3997 static const struct hda_amp_list ad1884a_loopbacks[] = {
4017 static int ad1884a_mobile_master_sw_put(
struct snd_kcontrol *kcontrol,
4022 int mute = (!ucontrol->
value.integer.value[0] &&
4023 !ucontrol->
value.integer.value[1]);
4034 .name =
"Master Playback Switch",
4038 .put = ad1884a_mobile_master_sw_put,
4063 .name =
"Master Playback Switch",
4067 .put = ad1884a_mobile_master_sw_put,
4080 static void ad1884a_hp_automute(
struct hda_codec *codec)
4082 unsigned int present;
4088 present ? 0x00 : 0x02);
4092 static void ad1884a_hp_automic(
struct hda_codec *codec)
4094 unsigned int present;
4101 #define AD1884A_HP_EVENT 0x37
4102 #define AD1884A_MIC_EVENT 0x36
4105 static void ad1884a_hp_unsol_event(
struct hda_codec *codec,
unsigned int res)
4107 switch (res >> 26) {
4109 ad1884a_hp_automute(codec);
4112 ad1884a_hp_automic(codec);
4118 static int ad1884a_hp_init(
struct hda_codec *codec)
4121 ad1884a_hp_automute(codec);
4122 ad1884a_hp_automic(codec);
4127 static void ad1884a_laptop_automute(
struct hda_codec *codec)
4129 unsigned int present;
4137 present ? 0x00 : 0x02);
4141 static void ad1884a_laptop_automic(
struct hda_codec *codec)
4155 static void ad1884a_laptop_unsol_event(
struct hda_codec *codec,
4158 switch (res >> 26) {
4160 ad1884a_laptop_automute(codec);
4163 ad1884a_laptop_automic(codec);
4169 static int ad1884a_laptop_init(
struct hda_codec *codec)
4172 ad1884a_laptop_automute(codec);
4173 ad1884a_laptop_automic(codec);
4178 static const struct hda_verb ad1884a_laptop_verbs[] = {
4209 static const struct hda_verb ad1884a_mobile_verbs[] = {
4264 static const struct hda_verb ad1984a_thinkpad_verbs[] = {
4294 .name =
"Capture Source",
4295 .info = ad198x_mux_enum_info,
4296 .get = ad198x_mux_enum_get,
4297 .put = ad198x_mux_enum_put,
4302 static const struct hda_input_mux ad1984a_thinkpad_capture_source = {
4306 {
"Internal Mic", 0x5 },
4312 static void ad1984a_thinkpad_automute(
struct hda_codec *codec)
4314 unsigned int present;
4322 static void ad1984a_thinkpad_unsol_event(
struct hda_codec *codec,
4327 ad1984a_thinkpad_automute(codec);
4331 static int ad1984a_thinkpad_init(
struct hda_codec *codec)
4334 ad1984a_thinkpad_automute(codec);
4345 static const struct hda_verb ad1984a_precision_verbs[] = {
4388 static void ad1984a_precision_automute(
struct hda_codec *codec)
4390 unsigned int present;
4399 static void ad1984a_precision_unsol_event(
struct hda_codec *codec,
4404 ad1984a_precision_automute(codec);
4408 static int ad1984a_precision_init(
struct hda_codec *codec)
4411 ad1984a_precision_automute(codec);
4427 static const struct hda_verb ad1984a_touchsmart_verbs[] = {
4485 .name =
"Master Playback Switch",
4488 .put = ad1884a_mobile_master_sw_put,
4501 static void ad1984a_touchsmart_automic(
struct hda_codec *codec)
4513 static void ad1984a_touchsmart_unsol_event(
struct hda_codec *codec,
4516 switch (res >> 26) {
4518 ad1884a_hp_automute(codec);
4521 ad1984a_touchsmart_automic(codec);
4527 static int ad1984a_touchsmart_init(
struct hda_codec *codec)
4530 ad1884a_hp_automute(codec);
4531 ad1984a_touchsmart_automic(codec);
4558 static const struct snd_pci_quirk ad1884a_cfg_tbl[] = {
4563 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x3070,
"HP",
AD1884A_MOBILE),
4564 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30d0,
"HP laptop",
AD1884A_LAPTOP),
4565 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30e0,
"HP laptop",
AD1884A_LAPTOP),
4566 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600,
"HP laptop",
AD1884A_LAPTOP),
4567 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010,
"HP laptop",
AD1884A_MOBILE),
4573 static int patch_ad1884a(
struct hda_codec *codec)
4576 int err, board_config;
4593 spec->
multiout.dac_nids = ad1884a_dac_nids;
4598 spec->
input_mux = &ad1884a_capture_source;
4600 spec->
mixers[0] = ad1884a_base_mixers;
4605 spec->loopback.amplist = ad1884a_loopbacks;
4613 switch (board_config) {
4615 spec->
mixers[0] = ad1884a_laptop_mixers;
4618 codec->
patch_ops.unsol_event = ad1884a_laptop_unsol_event;
4619 codec->
patch_ops.init = ad1884a_laptop_init;
4630 spec->
mixers[0] = ad1884a_mobile_mixers;
4633 codec->
patch_ops.unsol_event = ad1884a_hp_unsol_event;
4634 codec->
patch_ops.init = ad1884a_hp_init;
4645 spec->
mixers[0] = ad1984a_thinkpad_mixers;
4647 ad1984a_thinkpad_verbs;
4649 spec->
input_mux = &ad1984a_thinkpad_capture_source;
4650 codec->
patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
4651 codec->
patch_ops.init = ad1984a_thinkpad_init;
4654 spec->
mixers[0] = ad1984a_precision_mixers;
4656 ad1984a_precision_verbs;
4658 codec->
patch_ops.unsol_event = ad1984a_precision_unsol_event;
4659 codec->
patch_ops.init = ad1984a_precision_init;
4662 spec->
mixers[0] = ad1984a_touchsmart_mixers;
4663 spec->
init_verbs[0] = ad1984a_touchsmart_verbs;
4665 codec->
patch_ops.unsol_event = ad1984a_touchsmart_unsol_event;
4666 codec->
patch_ops.init = ad1984a_touchsmart_init;
4697 static const hda_nid_t ad1882_dac_nids[3] = {
4701 static const hda_nid_t ad1882_adc_nids[2] = {
4705 static const hda_nid_t ad1882_capsrc_nids[2] = {
4709 #define AD1882_SPDIF_OUT 0x02
4715 {
"Front Mic", 0x1 },
4724 static const struct hda_input_mux ad1882a_capture_source = {
4727 {
"Front Mic", 0x1 },
4730 {
"Digital Mic", 0x06 },
4758 .name =
"Input Source",
4760 .info = ad198x_mux_enum_info,
4761 .get = ad198x_mux_enum_get,
4762 .put = ad198x_mux_enum_put,
4770 .info = ad1983_spdif_route_info,
4771 .get = ad1983_spdif_route_get,
4772 .put = ad1983_spdif_route_put,
4808 .name =
"Channel Mode",
4809 .info = ad198x_ch_mode_info,
4810 .get = ad198x_ch_mode_get,
4811 .put = ad198x_ch_mode_put,
4817 #define AD1882_HP_EVENT 0x01
4819 static void ad1882_3stack_automute(
struct hda_codec *codec)
4826 static int ad1882_3stack_automute_init(
struct hda_codec *codec)
4829 ad1882_3stack_automute(codec);
4833 static void ad1882_3stack_unsol_event(
struct hda_codec *codec,
unsigned int res)
4835 switch (res >> 26) {
4837 ad1882_3stack_automute(codec);
4849 static const struct hda_verb ad1882_ch2_init[] = {
4859 static const struct hda_verb ad1882_ch4_init[] = {
4869 static const struct hda_verb ad1882_ch6_init[] = {
4880 { 2, ad1882_ch2_init },
4881 { 4, ad1882_ch4_init },
4882 { 6, ad1882_ch6_init },
4888 static const struct hda_verb ad1882_init_verbs[] = {
4956 static const struct hda_verb ad1882_3stack_automute_verbs[] = {
4962 static const struct hda_amp_list ad1882_loopbacks[] = {
4986 static int patch_ad1882(
struct hda_codec *codec)
4989 int err, board_config;
5006 spec->
multiout.dac_nids = ad1882_dac_nids;
5012 spec->
input_mux = &ad1882_capture_source;
5014 spec->
input_mux = &ad1882a_capture_source;
5016 spec->
mixers[0] = ad1882_base_mixers;
5018 spec->
mixers[1] = ad1882_loopback_mixers;
5020 spec->
mixers[1] = ad1882a_loopback_mixers;
5025 spec->loopback.amplist = ad1882_loopbacks;
5033 ad1882_models,
NULL);
5034 switch (board_config) {
5039 spec->
mixers[2] = ad1882_3stack_mixers;
5047 ad1882_3stack_automute_verbs;
5048 codec->
patch_ops.unsol_event = ad1882_3stack_unsol_event;
5049 codec->
patch_ops.init = ad1882_3stack_automute_init;
5054 spec->
mixers[2] = ad1882_6stack_mixers;
5069 { .id = 0x11d4184a, .name =
"AD1884A", .patch = patch_ad1884a },
5070 { .id = 0x11d41882, .name =
"AD1882", .patch = patch_ad1882 },
5071 { .id = 0x11d41883, .name =
"AD1883", .patch = patch_ad1884a },
5072 { .id = 0x11d41884, .name =
"AD1884", .patch = patch_ad1884 },
5073 { .id = 0x11d4194a, .name =
"AD1984A", .patch = patch_ad1884a },
5074 { .id = 0x11d4194b, .name =
"AD1984B", .patch = patch_ad1884a },
5075 { .id = 0x11d41981, .name =
"AD1981", .patch = patch_ad1981 },
5076 { .id = 0x11d41983, .name =
"AD1983", .patch = patch_ad1983 },
5077 { .id = 0x11d41984, .name =
"AD1984", .patch = patch_ad1984 },
5078 { .id = 0x11d41986, .name =
"AD1986A", .patch = patch_ad1986a },
5079 { .id = 0x11d41988, .name =
"AD1988", .patch = patch_ad1988 },
5080 { .id = 0x11d4198b, .name =
"AD1988B", .patch = patch_ad1988 },
5081 { .id = 0x11d4882a, .name =
"AD1882A", .patch = patch_ad1882 },
5082 { .id = 0x11d4989a, .name =
"AD1989A", .patch = patch_ad1988 },
5083 { .id = 0x11d4989b, .name =
"AD1989B", .patch = patch_ad1988 },
5093 .preset = snd_hda_preset_analog,
5097 static int __init patch_analog_init(
void)
5102 static void __exit patch_analog_exit(
void)